Skip to content

Commit

Permalink
GD-129: Spike to enable CSharp test support
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeSchulze committed Sep 6, 2021
1 parent ad8257a commit 460b9bd
Show file tree
Hide file tree
Showing 55 changed files with 1,892 additions and 136 deletions.
39 changes: 39 additions & 0 deletions .github/workflows/selftest-3.3.x-mono.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Run selftest Godot 3.3.x - Mono
on: [push]

jobs:
testing:
strategy:
matrix:
godot: [mono-3.3.1, mono-3.3.2, mono-3.3.3]

name: GdUnit3 Selftest on Godot ${{ matrix.godot }}
runs-on: ubuntu-latest
container:
image: barichello/godot-ci:${{ matrix.godot }}

steps:
- name: Checkout
uses: actions/checkout@v2
with:
lfs: true

- name: Compile
run: |
nuget restore
mkdir -p .mono/assemblies/Debug
cp /usr/local/bin/GodotSharp/Api/Release/* .mono/assemblies/Debug
msbuild
- name: Run Selftes
timeout-minutes: 5
env:
GODOT_BIN: "/usr/local/bin/godot"
shell: bash
run: ./runtest.sh --selftest

- name: Collect Test Reports
uses: actions/upload-artifact@v2
with:
name: Report_${{ matrix.godot }}
path: reports/**
9 changes: 4 additions & 5 deletions .github/workflows/selftest-3.3.x.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ jobs:
testing:
strategy:
matrix:
godot: [3.3, 3.3.1, 3.3.2, 3.3.3, mono-3.3.3]
godot: [3.3, 3.3.1, 3.3.2, 3.3.3]

name: GdUnit3 Selftest on Godot ${{ matrix.godot }}
runs-on: ubuntu-latest
container:
Expand All @@ -20,15 +20,14 @@ jobs:
- name: Setup
shell: bash
run: echo "GODOT_BIN=/usr/local/bin/godot" >> $GITHUB_ENV

- name: Run Selftes
shell: bash
run: ./runtest.sh --selftest

- name: Collect Test Report
if: always()
uses: actions/upload-artifact@v2
with:
name: Report_${{ matrix.godot }}
path: reports/**

13 changes: 7 additions & 6 deletions addons/gdUnit3/bin/GdUnitCmdTool.gd
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class CLIRunner extends Node:
_state = STOP
else:
# process next test suite
var test_suite := _test_suites_to_process.pop_front() as GdUnitTestSuite
var test_suite := _test_suites_to_process.pop_front() as GdUnitTestSuiteDelegator
var fs = _executor.execute(test_suite)
if fs is GDScriptFunctionState:
yield(fs, "completed")
Expand Down Expand Up @@ -201,7 +201,7 @@ class CLIRunner extends Node:
for test_suite in test_suites:
skip_suite(test_suite, skipped)

func skip_suite(test_suite :GdUnitTestSuite, skipped :Dictionary) -> void:
func skip_suite(test_suite :GdUnitTestSuiteDelegator, skipped :Dictionary) -> void:
var skipped_suites := skipped.keys()
if skipped_suites.empty():
return
Expand All @@ -217,7 +217,7 @@ class CLIRunner extends Node:
else:
# skip tests
for test_to_skip in skipped_tests:
var test_case :_TestCase = test_suite.find_node(test_to_skip, true, false)
var test_case :_TestCase = test_suite.get_test_case_by_name(test_to_skip)
if test_case:
test_case.skip(true)
else:
Expand All @@ -244,21 +244,22 @@ class CLIRunner extends Node:
_report.add_testsuite_report(GdUnitTestSuiteReport.new(event.resource_path(), event.suite_name()))

GdUnitEvent.TESTSUITE_AFTER:
_report.update_test_suite_report(event.suite_name(), event.skipped_count(), event.orphan_nodes(), event.elapsed_time())
_report.update_test_suite_report(event.resource_path(), event.skipped_count(), event.orphan_nodes(), event.elapsed_time())

GdUnitEvent.TESTCASE_BEFORE:
_report.add_testcase_report(event.suite_name(), GdUnitTestCaseReport.new(event.test_name()))
_report.add_testcase_report(event.resource_path(), GdUnitTestCaseReport.new(event.resource_path(), event.test_name()))

GdUnitEvent.TESTCASE_AFTER:
var test_report := GdUnitTestCaseReport.new(
event.resource_path(),
event.test_name(),
event.is_error(),
event.is_failed(),
event.orphan_nodes(),
event.skipped_count(),
event.reports(),
event.elapsed_time())
_report.update_testcase_report(event.suite_name(), test_report)
_report.update_testcase_report(event.resource_path(), test_report)
print_status(event)

func report_exit_code(report :GdUnitHtmlReport) -> int:
Expand Down
2 changes: 1 addition & 1 deletion addons/gdUnit3/plugin.gd
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func _enter_tree():
# show possible update notification when is enabled
if GdUnitSettings.is_update_notification_enabled():
_update_tool = load("res://addons/gdUnit3/src/update/GdUnitUpdate.tscn").instance()
get_parent().add_child(_update_tool)
add_child(_update_tool)

# install SignalHandler singleton
GdUnitSingleton.add_singleton(SignalHandler.SINGLETON_NAME, "res://addons/gdUnit3/src/core/event/SignalHandler.gd")
Expand Down
2 changes: 1 addition & 1 deletion addons/gdUnit3/src/GdUnitStringAssert.gd
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@ func ends_with(expected: String) -> GdUnitStringAssert:
return self

# Verifies that the current String has the expected length by used comparator.
func has_length(lenght: int, comparator: int = Comparator.EXACTLY) -> GdUnitStringAssert:
func has_length(lenght: int, comparator: int = Comparator.EQUAL) -> GdUnitStringAssert:
return self
151 changes: 151 additions & 0 deletions addons/gdUnit3/src/GdUnitTestSuite.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
using Godot;
using System;

namespace GdUnit3
{

/** <summary>
This class is the main class to implement your unit tests<br />
You have to extend and implement your test cases as described<br />
e.g<br />
<br />
For detailed instructions see <a href="https://github.com/MikeSchulze/gdUnit3/wiki/TestSuite">HERE</a> <br />
<example>For example:
<code>
public class MyExampleTest : GdUnit3.GdUnitTestSuite
{
public void test_testCaseA()
{
assertThat("value").isEqual("value");
}
}
</code>
</example>
</summary> */
public abstract class GdUnitTestSuite : Node
{


[AttributeUsage(AttributeTargets.Class)]
public class TestSuiteAttribute : Attribute
{
}

[AttributeUsage(AttributeTargets.Method)]
public class TestCaseAttribute : Attribute
{
public readonly int Timeout = -1;
public readonly int Line;

public TestCaseAttribute([System.Runtime.CompilerServices.CallerLineNumber] int line = 0)
{
Line = line;
}
}


private bool _scipped = false;
private String _active_test_case;

private static Godot.Resource GdUnitTools = (Resource)GD.Load<GDScript>("res://addons/gdUnit3/src/core/GdUnitTools.gd").New();



~GdUnitTestSuite()
{
}

/// <summary>
/// This function is called before a test suite starts
/// You can overwrite to prepare test data or initalizize necessary variables
/// </summary>
public virtual void Before() { }

// This function is called at least when a test suite is finished
// You can overwrite to cleanup data created during test running
public virtual void After() { }

// This function is called before a test case starts
// You can overwrite to prepare test case specific data
public virtual void BeforeTest() { }

// This function is called after the test case is finished
// You can overwrite to cleanup your test case specific data
public virtual void AfterTest() { }

// Skip the test-suite from execution, it will be ignored
public void skip(bool skipped) => _scipped = skipped;

public bool is_skipped => _scipped;

public void set_active_test_case(String test_case) => _active_test_case = test_case;

// === Tools ====================================================================
// Mapps Godot error number to a readable error message. See at ERROR
// https://docs.godotengine.org/de/stable/classes/[email protected]#enum-globalscope-error
public String error_as_string(int error_number)
{
return (String)GdUnitTools.Call("error_as_string", error_number);
}

// A litle helper to auto freeing your created objects after test execution
public T auto_free<T>(T obj)
{
GdUnitTools.Call("register_auto_free", obj, GetMeta("MEMORY_POOL"));
return obj;
}

// Discard the error message triggered by a timeout (interruption).
// By default, an interrupted test is reported as an error.
// This function allows you to change the message to Success when an interrupted error is reported.
public void discard_error_interupted_by_timeout()
{
//GdUnitTools.register_expect_interupted_by_timeout(self, __active_test_case)
}

// Creates a new directory under the temporary directory *user://tmp*
// Useful for storing data during test execution.
// The directory is automatically deleted after test suite execution
public String create_temp_dir(String relative_path)
{
//return GdUnitTools.create_temp_dir(relative_path)
return "";
}

// Deletes the temporary base directory
// Is called automatically after each execution of the test suite
public void clean_temp_dir()
{
//GdUnitTools.clear_tmp()
}

// === Asserts ==================================================================
public IGdUnitBoolAssert AssertBool(bool current, IGdUnitAssert.EXPECT expectResult = IGdUnitAssert.EXPECT.SUCCESS)
{
return new GdUnitBoolAssertWrapper(this, current, expectResult);
}

public IGdUnitStringAssert AssertString(string current, IGdUnitAssert.EXPECT expectResult = IGdUnitAssert.EXPECT.SUCCESS)
{
return new GdUnitStringAssertWrapper(this, current, expectResult);
}

public IGdUnitIntAssert AssertInt(int current, IGdUnitAssert.EXPECT expectResult = IGdUnitAssert.EXPECT.SUCCESS)
{
return new GdUnitIntAssertWrapper(this, current, expectResult);
}

public IGdUnitFloatAssert AssertFloat(double current, IGdUnitAssert.EXPECT expectResult = IGdUnitAssert.EXPECT.SUCCESS)
{
return new GdUnitFloatAssertWrapper(this, current, expectResult);
}

public IGdUnitObjectAssert AssertObject(object current, IGdUnitAssert.EXPECT expectResult = IGdUnitAssert.EXPECT.SUCCESS)
{
return new GdUnitObjectAssertWrapper(this, current, expectResult);
}
}

}
48 changes: 48 additions & 0 deletions addons/gdUnit3/src/IGdUnitAssert.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System;
using System.ComponentModel;

namespace GdUnit3
{

/// <summary> Main interface of all GdUnit asserts </summary>
public interface IGdUnitAssert
{

enum EXPECT : int
{
[Description("assert expects ends with success")]
SUCCESS = 0,
[Description("assert expects ends with errors")]
FAIL = 1
}
}

/// <summary> Base interface of all GdUnit asserts </summary>
public interface IGdUnitAssertBase<V> : IGdUnitAssert
{

/// <summary>Verifies that the current value is null.</summary>
IGdUnitAssertBase<V> IsNull();

/// <summary> Verifies that the current value is not null.</summary>
IGdUnitAssertBase<V> IsNotNull();

/// <summary> Verifies that the current value is equal to expected one.
IGdUnitAssertBase<V> IsEqual(V expected);

/// <summary> Verifies that the current value is not equal to expected one.</summary>
IGdUnitAssertBase<V> IsNotEqual(V expected);

/// <summary></summary>
IGdUnitAssertBase<V> TestFail();

/// <summary> Verifies the failure message is equal to expected one.</summary>
IGdUnitAssertBase<V> HasFailureMessage(string expected);

/// <summary> Verifies that the failure starts with the given value.</summary>
IGdUnitAssertBase<V> StartsWithFailureMessage(string value);

/// <summary> Overrides the default failure message by given custom message.</summary>
IGdUnitAssertBase<V> OverrideFailureMessage(string message);
}
}
18 changes: 18 additions & 0 deletions addons/gdUnit3/src/IGdUnitBoolAssert.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Godot;
using System;

namespace GdUnit3
{

/// <summary> An Assertion Tool to verify boolean values </summary>
public interface IGdUnitBoolAssert : IGdUnitAssertBase<bool>
{

/// <summary> Verifies that the current value is true.</summary>
IGdUnitBoolAssert IsTrue();

/// <summary> Verifies that the current value is false.</summary>
IGdUnitBoolAssert IsFalse();

}
}
9 changes: 9 additions & 0 deletions addons/gdUnit3/src/IGdUnitFloatAssert.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace GdUnit3
{

/// <summary> Base interface for integer assertions.</summary>
public interface IGdUnitFloatAssert : IGdUnitNumberAssert<double>
{

}
}
9 changes: 9 additions & 0 deletions addons/gdUnit3/src/IGdUnitIntAssert.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace GdUnit3
{

/// <summary> Base interface for integer assertions.</summary>
public interface IGdUnitIntAssert : IGdUnitNumberAssert<int>
{

}
}
Loading

0 comments on commit 460b9bd

Please sign in to comment.