Compare commits
47 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cc973b9f0d | |||
| 8a552f7993 | |||
| 93841bc85d | |||
| 9ba8847626 | |||
| 51b7328310 | |||
| fdc352596d | |||
| 89ba5cc985 | |||
| fdc79166a0 | |||
| b84487336b | |||
| e4ab103c4d | |||
| 3b6cf0252b | |||
| e908cd3085 | |||
| 6b23fdbd26 | |||
| ea6258ff19 | |||
| 5e54f0f83b | |||
| f00439a430 | |||
| 02ec230b3f | |||
| 867554b835 | |||
| a4835eeb3c | |||
| 55b877226e | |||
| d7d33d0dac | |||
| f92c6d282f | |||
| 2d41523668 | |||
| 34b04a365a | |||
| d0ac644e14 | |||
| 510a3200d1 | |||
| bef601941c | |||
| b6605d6293 | |||
| 1b6742ea45 | |||
| 405e487881 | |||
| af1f6da98d | |||
| 119850a7b4 | |||
| b198aba09b | |||
| 37165d1562 | |||
| 5684561b66 | |||
| 2678cac0e6 | |||
| 230b409abe | |||
| a6c80206c9 | |||
| 1a73f23670 | |||
| 38e62dcbb3 | |||
| 19bdc143c1 | |||
| 1709554e72 | |||
| 5c2e9408c5 | |||
| caeae26a09 | |||
| 056a68b0ad | |||
| f1f0febf29 | |||
| 916a6e7153 |
@@ -10,47 +10,31 @@ on:
|
||||
- "**"
|
||||
|
||||
env:
|
||||
GODOT_VERSION: 4.6
|
||||
GAME_NAME: MovementTests
|
||||
ITCHIO_USERNAME: Minimata
|
||||
ITCHIO_GAMEID: MovementTests
|
||||
|
||||
jobs:
|
||||
Export:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: godot
|
||||
steps:
|
||||
- name: Install node, xvfb and curl
|
||||
run: |
|
||||
apt update && apt -y install curl nodejs xvfb
|
||||
- name: Checkout with LFS
|
||||
uses: https://git.game-dev.space/minimata/checkout-with-lfs.git@main
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
lfs: false
|
||||
persist-credentials: true
|
||||
|
||||
- name: Checkout LFS
|
||||
run: |
|
||||
git lfs install --local
|
||||
AUTH=$(git config http.${{ gitea.server_url }}/.extraheader)
|
||||
AUTH_FILE=$(git config includeif.gitdir:/workspace/${{ gitea.repository }}/.git.path)
|
||||
git config -f $AUTH_FILE --unset http.${{ gitea.server_url }}/.extraheader
|
||||
git config -f $AUTH_FILE http.${{ gitea.server_url }}/${{ gitea.repository }}.git/info/lfs/objects/batch.extraheader "$AUTH"
|
||||
git lfs pull
|
||||
|
||||
- name: Run tests
|
||||
uses: godot-gdunit-labs/gdUnit4-action@v1
|
||||
with:
|
||||
godot-version: '4.5.1'
|
||||
godot-version: ${GODOT_VERSION}
|
||||
godot-net: true
|
||||
godot-force-mono: true
|
||||
dotnet-version: 'net9.0'
|
||||
version: 'v6.0.3'
|
||||
paths: |
|
||||
res://tests/
|
||||
timeout: 1
|
||||
publish-report: false
|
||||
upload-report: false
|
||||
|
||||
|
||||
- name: Upload test report
|
||||
uses: actions/upload-artifact@v3-node20
|
||||
with:
|
||||
|
||||
@@ -8,6 +8,7 @@ on:
|
||||
- "**"
|
||||
|
||||
env:
|
||||
GODOT_VERSION: 4.6
|
||||
GAME_NAME: MovementTests
|
||||
ITCHIO_USERNAME: Minimata
|
||||
ITCHIO_GAMEID: MovementTests
|
||||
@@ -21,6 +22,7 @@ jobs:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.TOKEN }}
|
||||
lfs: false
|
||||
- name: Remove buggy pre-push hook
|
||||
run: |
|
||||
@@ -37,35 +39,20 @@ jobs:
|
||||
DEFAULT_BUMP: patch
|
||||
|
||||
Test:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: godot
|
||||
# env:
|
||||
# RUNNER_TOOL_CACHE: /toolcache # Runner Tool Cache
|
||||
steps:
|
||||
- name: Install node, xvfb and curl
|
||||
run: |
|
||||
apt update && apt -y install curl nodejs xvfb
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
lfs: false
|
||||
persist-credentials: true
|
||||
|
||||
- name: Checkout LFS
|
||||
run: |
|
||||
git lfs install --local
|
||||
AUTH=$(git config http.${{ gitea.server_url }}/.extraheader)
|
||||
AUTH_FILE=$(git config includeif.gitdir:/workspace/${{ gitea.repository }}/.git.path)
|
||||
git config -f $AUTH_FILE --unset http.${{ gitea.server_url }}/.extraheader
|
||||
git config -f $AUTH_FILE http.${{ gitea.server_url }}/${{ gitea.repository }}.git/info/lfs/objects/batch.extraheader "$AUTH"
|
||||
git lfs pull
|
||||
- name: Checkout with LFS
|
||||
uses: https://git.game-dev.space/minimata/checkout-with-lfs.git@main
|
||||
|
||||
- name: Run tests
|
||||
uses: godot-gdunit-labs/gdUnit4-action@v1
|
||||
with:
|
||||
godot-version: '4.5.1'
|
||||
godot-version: ${GODOT_VERSION}
|
||||
godot-net: true
|
||||
godot-force-mono: true
|
||||
dotnet-version: 'net9.0'
|
||||
version: 'v6.0.3'
|
||||
paths: |
|
||||
res://tests/
|
||||
timeout: 1
|
||||
@@ -79,52 +66,51 @@ jobs:
|
||||
path: ${{ github.workspace }}/reports/test-result.html
|
||||
|
||||
Export:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: godot
|
||||
needs:
|
||||
- BumpTag
|
||||
- Test # Wait for tests to finish
|
||||
container:
|
||||
image: barichello/godot-ci:mono-4.5
|
||||
|
||||
steps:
|
||||
- name: Install node, curl and zip
|
||||
run: |
|
||||
apt update && apt -y install curl zip nodejs
|
||||
- name: Checkout with LFS
|
||||
uses: https://git.game-dev.space/minimata/checkout-with-lfs.git@main
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
- name: Setup Godot
|
||||
id: setup-godot
|
||||
uses: https://git.game-dev.space/minimata/setup-godot.git@main
|
||||
with:
|
||||
lfs: false
|
||||
persist-credentials: true
|
||||
|
||||
- name: Checkout LFS
|
||||
run: |
|
||||
git lfs install --local
|
||||
AUTH=$(git config http.${{ gitea.server_url }}/.extraheader)
|
||||
AUTH_FILE=$(git config includeif.gitdir:/workspace/${{ gitea.repository }}/.git.path)
|
||||
git config -f $AUTH_FILE --unset http.${{ gitea.server_url }}/.extraheader
|
||||
git config -f $AUTH_FILE http.${{ gitea.server_url }}/${{ gitea.repository }}.git/info/lfs/objects/batch.extraheader "$AUTH"
|
||||
git lfs pull
|
||||
|
||||
- name: Remove GDUnit addon folder because it breaks the build
|
||||
godot-version: '4.6'
|
||||
dotnet-version: 'net9.0'
|
||||
|
||||
- name: Remove GDUnit addon
|
||||
run: |
|
||||
rm -rf ${{ gitea.workspace }}/addons/gdUnit4
|
||||
|
||||
- name: Import resources and build solution
|
||||
run: |
|
||||
godot --headless --editor --build-solutions --quit --import --path $PWD
|
||||
|
||||
|
||||
- name: Build Windows
|
||||
run: |
|
||||
mkdir -v -p build/windows
|
||||
godot --headless --verbose --build-solutions --export-release "Windows Desktop" build/windows/${{ env.GAME_NAME }}.exe
|
||||
${{ steps.setup-godot.outputs.godot_bin }} --headless --verbose --export-release "Windows Desktop" build/windows/${{ env.GAME_NAME }}.exe
|
||||
zip -r Windows.zip build/windows
|
||||
- name: Upload to Itch
|
||||
uses: KikimoraGames/itch-publish@v0.0.3
|
||||
with:
|
||||
butlerApiKey: ${{ secrets.BUTLER_TOKEN }}
|
||||
itchUsername: ${{ env.ITCHIO_USERNAME }}
|
||||
itchGameId: ${{ env.ITCHIO_GAMEID }}
|
||||
buildNumber: ${{ needs.BumpTag.outputs.tag_name }}
|
||||
gameData: Windows.zip
|
||||
buildChannel: windows
|
||||
|
||||
- name: Setup Butler
|
||||
shell: bash
|
||||
env:
|
||||
BUTLER_API_KEY: ${{ secrets.BUTLER_TOKEN }}
|
||||
run: |
|
||||
mkdir ./tools 2>/dev/null || true
|
||||
pushd tools
|
||||
curl -sSLfo ./butler.zip "https://broth.itch.zone/butler/linux-amd64/LATEST/archive/default"
|
||||
unzip butler.zip
|
||||
chmod +x ./butler
|
||||
popd
|
||||
./tools/butler -V
|
||||
|
||||
- name: Upload to itch.io
|
||||
shell: bash
|
||||
env:
|
||||
BUTLER_API_KEY: ${{ secrets.BUTLER_TOKEN }}
|
||||
run: |
|
||||
versionArgument="--userversion ${{ needs.BumpTag.outputs.tag_name }}"
|
||||
./tools/butler push \
|
||||
"Windows.zip" \
|
||||
${{ env.ITCHIO_USERNAME }}/${{ env.ITCHIO_GAMEID }}:windows ${versionArgument}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ on:
|
||||
- "**"
|
||||
|
||||
env:
|
||||
GODOT_VERSION: 4.6
|
||||
GAME_NAME: MovementTests
|
||||
ITCHIO_USERNAME: Minimata
|
||||
ITCHIO_GAMEID: MovementTests
|
||||
@@ -26,92 +27,90 @@ jobs:
|
||||
separator: '/'
|
||||
|
||||
Release:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: godot
|
||||
if: ${{ contains(gitea.ref_name, 'release/') }}
|
||||
needs: ReleaseName
|
||||
container:
|
||||
image: barichello/godot-ci:mono-4.5
|
||||
|
||||
steps:
|
||||
- name: Install node, curl and zip
|
||||
run: |
|
||||
apt update && apt -y install curl zip nodejs
|
||||
- name: Checkout with LFS
|
||||
uses: https://git.game-dev.space/minimata/checkout-with-lfs.git@main
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
- name: Setup Godot
|
||||
id: setup-godot
|
||||
uses: https://git.game-dev.space/minimata/setup-godot.git@main
|
||||
with:
|
||||
lfs: false
|
||||
persist-credentials: true
|
||||
|
||||
- name: Checkout LFS
|
||||
godot-version: '4.6'
|
||||
dotnet-version: 'net9.0'
|
||||
|
||||
- name: Setup Butler
|
||||
shell: bash
|
||||
env:
|
||||
BUTLER_API_KEY: ${{ secrets.BUTLER_TOKEN }}
|
||||
run: |
|
||||
git lfs install --local
|
||||
AUTH=$(git config http.${{ gitea.server_url }}/.extraheader)
|
||||
AUTH_FILE=$(git config includeif.gitdir:/workspace/${{ gitea.repository }}/.git.path)
|
||||
git config -f $AUTH_FILE --unset http.${{ gitea.server_url }}/.extraheader
|
||||
git config -f $AUTH_FILE http.${{ gitea.server_url }}/${{ gitea.repository }}.git/info/lfs/objects/batch.extraheader "$AUTH"
|
||||
git lfs pull
|
||||
|
||||
- name: Import resources and build solution
|
||||
run: |
|
||||
godot --headless --editor --build-solutions --quit --import --path $PWD
|
||||
mkdir ./tools 2>/dev/null || true
|
||||
pushd tools
|
||||
curl -sSLfo ./butler.zip "https://broth.itch.zone/butler/linux-amd64/LATEST/archive/default"
|
||||
unzip butler.zip
|
||||
chmod +x ./butler
|
||||
popd
|
||||
./tools/butler -V
|
||||
|
||||
- name: Build Windows
|
||||
run: |
|
||||
mkdir -v -p build/windows
|
||||
godot --headless --verbose --build-solutions --export-release "Windows Desktop" build/windows/${{ env.GAME_NAME }}.exe
|
||||
zip -r Windows.zip build/windows
|
||||
- name: Upload to Itch
|
||||
uses: KikimoraGames/itch-publish@v0.0.3
|
||||
with:
|
||||
butlerApiKey: ${{ secrets.BUTLER_TOKEN }}
|
||||
itchUsername: ${{ env.ITCHIO_USERNAME }}
|
||||
itchGameId: ${{ env.ITCHIO_GAMEID }}
|
||||
buildNumber: ${{ needs.ReleaseName.outputs.release_name }}
|
||||
gameData: Windows.zip
|
||||
buildChannel: windows
|
||||
- name: Upload Windows to itch.io
|
||||
shell: bash
|
||||
env:
|
||||
BUTLER_API_KEY: ${{ secrets.BUTLER_TOKEN }}
|
||||
run: |
|
||||
versionArgument="--userversion ${{ needs.ReleaseName.outputs.release_name }}"
|
||||
./tools/butler push \
|
||||
"Windows.zip" \
|
||||
${{ env.ITCHIO_USERNAME }}/${{ env.ITCHIO_GAMEID }}:windows ${versionArgument}
|
||||
|
||||
- name: Build Windows ARM
|
||||
run: |
|
||||
mkdir -v -p build/windowsArm
|
||||
godot --headless --verbose --build-solutions --export-release "Windows ARM" build/windowsArm/${{ env.GAME_NAME }}.exe
|
||||
zip -r WindowsArm.zip build/windowsArm
|
||||
- name: Upload to Itch
|
||||
uses: KikimoraGames/itch-publish@v0.0.3
|
||||
with:
|
||||
butlerApiKey: ${{ secrets.BUTLER_TOKEN }}
|
||||
itchUsername: ${{ env.ITCHIO_USERNAME }}
|
||||
itchGameId: ${{ env.ITCHIO_GAMEID }}
|
||||
buildNumber: ${{ needs.ReleaseName.outputs.release_name }}
|
||||
gameData: WindowsArm.zip
|
||||
buildChannel: windows-arm
|
||||
- name: Upload Windows to itch.io
|
||||
shell: bash
|
||||
env:
|
||||
BUTLER_API_KEY: ${{ secrets.BUTLER_TOKEN }}
|
||||
run: |
|
||||
versionArgument="--userversion ${{ needs.ReleaseName.outputs.release_name }}"
|
||||
./tools/butler push \
|
||||
"WindowsArm.zip" \
|
||||
${{ env.ITCHIO_USERNAME }}/${{ env.ITCHIO_GAMEID }}:windows-arm ${versionArgument}
|
||||
|
||||
- name: Linux Build
|
||||
run: |
|
||||
mkdir -v -p build/linux
|
||||
godot --headless --verbose --export-release "Linux/X11" build/linux/${{ env.GAME_NAME }}.x86_64
|
||||
zip -r Linux.zip build/linux
|
||||
- name: Upload to Itch
|
||||
uses: KikimoraGames/itch-publish@v0.0.3
|
||||
with:
|
||||
butlerApiKey: ${{ secrets.BUTLER_TOKEN }}
|
||||
itchUsername: ${{ env.ITCHIO_USERNAME }}
|
||||
itchGameId: ${{ env.ITCHIO_GAMEID }}
|
||||
buildNumber: ${{ needs.ReleaseName.outputs.release_name }}
|
||||
gameData: Linux.zip
|
||||
buildChannel: linux
|
||||
- name: Upload Windows to itch.io
|
||||
shell: bash
|
||||
env:
|
||||
BUTLER_API_KEY: ${{ secrets.BUTLER_TOKEN }}
|
||||
run: |
|
||||
versionArgument="--userversion ${{ needs.ReleaseName.outputs.release_name }}"
|
||||
./tools/butler push \
|
||||
"Linux.zip" \
|
||||
${{ env.ITCHIO_USERNAME }}/${{ env.ITCHIO_GAMEID }}:linux ${versionArgument}
|
||||
|
||||
- name: Mac Build
|
||||
run: |
|
||||
mkdir -v -p build/mac
|
||||
godot --headless --verbose --export-release "macOS" build/mac/${{ env.GAME_NAME }}.zip
|
||||
zip -r Mac.zip build/mac
|
||||
- name: Upload to Itch
|
||||
uses: KikimoraGames/itch-publish@v0.0.3
|
||||
with:
|
||||
butlerApiKey: ${{ secrets.BUTLER_TOKEN }}
|
||||
itchUsername: ${{ env.ITCHIO_USERNAME }}
|
||||
itchGameId: ${{ env.ITCHIO_GAMEID }}
|
||||
buildNumber: ${{ needs.ReleaseName.outputs.release_name }}
|
||||
gameData: Mac.zip
|
||||
buildChannel: mac
|
||||
- name: Upload Windows to itch.io
|
||||
shell: bash
|
||||
env:
|
||||
BUTLER_API_KEY: ${{ secrets.BUTLER_TOKEN }}
|
||||
run: |
|
||||
versionArgument="--userversion ${{ needs.ReleaseName.outputs.release_name }}"
|
||||
./tools/butler push \
|
||||
"Mac.zip" \
|
||||
${{ env.ITCHIO_USERNAME }}/${{ env.ITCHIO_GAMEID }}:mac ${versionArgument}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Godot.NET.Sdk/4.5.0">
|
||||
<Project Sdk="Godot.NET.Sdk/4.6.0">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
@@ -131,9 +131,9 @@
|
||||
</ItemGroup>
|
||||
<!-- gdUnit4 package dependencies -->
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.0"/>
|
||||
<PackageReference Include="gdUnit4.api" Version="5.1.0-rc3"/>
|
||||
<PackageReference Include="gdUnit4.test.adapter" Version="3.0.0"/>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.0" />
|
||||
<PackageReference Include="gdUnit4.api" Version="5.1.0-rc3" />
|
||||
<PackageReference Include="gdUnit4.test.adapter" Version="3.0.0" />
|
||||
<PackageReference Include="gdUnit4.analyzers" Version="1.0.0">
|
||||
<PrivateAssets>none</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
||||
142
Movement tests.csproj.old.1
Normal file
142
Movement tests.csproj.old.1
Normal file
@@ -0,0 +1,142 @@
|
||||
<Project Sdk="Godot.NET.Sdk/4.5.0">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
<RootNamespace>Movementtests</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Content Include=".runsettings" />
|
||||
<Content Include="export_presets.cfg" />
|
||||
<Content Include="menus\assets\git_logo\Git-Logo-2Color.png" />
|
||||
<Content Include="menus\assets\git_logo\Git-Logo-2Color.png.import" />
|
||||
<Content Include="menus\assets\git_logo\LICENSE.txt" />
|
||||
<Content Include="menus\assets\godot_engine_logo\LICENSE.txt" />
|
||||
<Content Include="menus\assets\godot_engine_logo\logo_vertical_color_dark.png" />
|
||||
<Content Include="menus\assets\godot_engine_logo\logo_vertical_color_dark.png.import" />
|
||||
<Content Include="menus\assets\icon.png" />
|
||||
<Content Include="menus\assets\icon.png.import" />
|
||||
<Content Include="menus\ATTRIBUTION.md" />
|
||||
<Content Include="menus\resources\themes\expedition.tres" />
|
||||
<Content Include="menus\resources\themes\gravity.tres" />
|
||||
<Content Include="menus\resources\themes\grow.tres" />
|
||||
<Content Include="menus\resources\themes\lab.tres" />
|
||||
<Content Include="menus\resources\themes\lore.tres" />
|
||||
<Content Include="menus\resources\themes\steal_this_theme.tres" />
|
||||
<Content Include="menus\scenes\credits\scrollable_credits.gd" />
|
||||
<Content Include="menus\scenes\credits\scrollable_credits.gd.uid" />
|
||||
<Content Include="menus\scenes\credits\scrollable_credits.tscn" />
|
||||
<Content Include="menus\scenes\credits\scrolling_credits.gd" />
|
||||
<Content Include="menus\scenes\credits\scrolling_credits.gd.uid" />
|
||||
<Content Include="menus\scenes\credits\scrolling_credits.tscn" />
|
||||
<Content Include="menus\scenes\end_credits\end_credits.gd" />
|
||||
<Content Include="menus\scenes\end_credits\end_credits.gd.uid" />
|
||||
<Content Include="menus\scenes\end_credits\end_credits.tscn" />
|
||||
<Content Include="menus\scenes\game_scene\configurable_sub_viewport.gd" />
|
||||
<Content Include="menus\scenes\game_scene\configurable_sub_viewport.gd.uid" />
|
||||
<Content Include="menus\scenes\game_scene\game_ui.tscn" />
|
||||
<Content Include="menus\scenes\game_scene\input_display_label.gd" />
|
||||
<Content Include="menus\scenes\game_scene\input_display_label.gd.uid" />
|
||||
<Content Include="menus\scenes\game_scene\levels\level.gd" />
|
||||
<Content Include="menus\scenes\game_scene\levels\level.gd.uid" />
|
||||
<Content Include="menus\scenes\game_scene\levels\level_1.tscn" />
|
||||
<Content Include="menus\scenes\game_scene\levels\level_2.tscn" />
|
||||
<Content Include="menus\scenes\game_scene\levels\level_3.tscn" />
|
||||
<Content Include="menus\scenes\game_scene\tutorials\tutorial_1.tscn" />
|
||||
<Content Include="menus\scenes\game_scene\tutorials\tutorial_2.tscn" />
|
||||
<Content Include="menus\scenes\game_scene\tutorials\tutorial_3.tscn" />
|
||||
<Content Include="menus\scenes\game_scene\tutorial_manager.gd" />
|
||||
<Content Include="menus\scenes\game_scene\tutorial_manager.gd.uid" />
|
||||
<Content Include="menus\scenes\loading_screen\level_loading_screen.tscn" />
|
||||
<Content Include="menus\scenes\loading_screen\loading_screen.gd" />
|
||||
<Content Include="menus\scenes\loading_screen\loading_screen.gd.uid" />
|
||||
<Content Include="menus\scenes\loading_screen\loading_screen.tscn" />
|
||||
<Content Include="menus\scenes\loading_screen\loading_screen_with_shader_caching.gd" />
|
||||
<Content Include="menus\scenes\loading_screen\loading_screen_with_shader_caching.gd.uid" />
|
||||
<Content Include="menus\scenes\loading_screen\loading_screen_with_shader_caching.tscn" />
|
||||
<Content Include="menus\scenes\menus\level_select_menu\level_select_menu.gd" />
|
||||
<Content Include="menus\scenes\menus\level_select_menu\level_select_menu.gd.uid" />
|
||||
<Content Include="menus\scenes\menus\level_select_menu\level_select_menu.tscn" />
|
||||
<Content Include="menus\scenes\menus\main_menu\main_menu.gd" />
|
||||
<Content Include="menus\scenes\menus\main_menu\main_menu.gd.uid" />
|
||||
<Content Include="menus\scenes\menus\main_menu\main_menu.tscn" />
|
||||
<Content Include="menus\scenes\menus\main_menu\main_menu_with_animations.gd" />
|
||||
<Content Include="menus\scenes\menus\main_menu\main_menu_with_animations.gd.uid" />
|
||||
<Content Include="menus\scenes\menus\main_menu\main_menu_with_animations.tscn" />
|
||||
<Content Include="menus\scenes\menus\options_menu\audio\audio_input_option_control.gd" />
|
||||
<Content Include="menus\scenes\menus\options_menu\audio\audio_input_option_control.gd.uid" />
|
||||
<Content Include="menus\scenes\menus\options_menu\audio\audio_input_option_control.tscn" />
|
||||
<Content Include="menus\scenes\menus\options_menu\audio\audio_options_menu.gd" />
|
||||
<Content Include="menus\scenes\menus\options_menu\audio\audio_options_menu.gd.uid" />
|
||||
<Content Include="menus\scenes\menus\options_menu\audio\audio_options_menu.tscn" />
|
||||
<Content Include="menus\scenes\menus\options_menu\game\game_options_menu.gd" />
|
||||
<Content Include="menus\scenes\menus\options_menu\game\game_options_menu.gd.uid" />
|
||||
<Content Include="menus\scenes\menus\options_menu\game\game_options_menu.tscn" />
|
||||
<Content Include="menus\scenes\menus\options_menu\game\reset_game_control\reset_game_control.gd" />
|
||||
<Content Include="menus\scenes\menus\options_menu\game\reset_game_control\reset_game_control.gd.uid" />
|
||||
<Content Include="menus\scenes\menus\options_menu\game\reset_game_control\reset_game_control.tscn" />
|
||||
<Content Include="menus\scenes\menus\options_menu\input\input_extras_menu.tscn" />
|
||||
<Content Include="menus\scenes\menus\options_menu\input\input_options_menu.gd" />
|
||||
<Content Include="menus\scenes\menus\options_menu\input\input_options_menu.gd.uid" />
|
||||
<Content Include="menus\scenes\menus\options_menu\input\input_options_menu.tscn" />
|
||||
<Content Include="menus\scenes\menus\options_menu\input\input_options_menu_with_mouse_sensitivity.tscn" />
|
||||
<Content Include="menus\scenes\menus\options_menu\master_options_menu.gd" />
|
||||
<Content Include="menus\scenes\menus\options_menu\master_options_menu.gd.uid" />
|
||||
<Content Include="menus\scenes\menus\options_menu\master_options_menu.tscn" />
|
||||
<Content Include="menus\scenes\menus\options_menu\master_options_menu_with_tabs.tscn" />
|
||||
<Content Include="menus\scenes\menus\options_menu\mini_options_menu.gd" />
|
||||
<Content Include="menus\scenes\menus\options_menu\mini_options_menu.gd.uid" />
|
||||
<Content Include="menus\scenes\menus\options_menu\mini_options_menu.tscn" />
|
||||
<Content Include="menus\scenes\menus\options_menu\mini_options_menu_with_reset.gd" />
|
||||
<Content Include="menus\scenes\menus\options_menu\mini_options_menu_with_reset.gd.uid" />
|
||||
<Content Include="menus\scenes\menus\options_menu\mini_options_menu_with_reset.tscn" />
|
||||
<Content Include="menus\scenes\menus\options_menu\video\video_options_menu.gd" />
|
||||
<Content Include="menus\scenes\menus\options_menu\video\video_options_menu.gd.uid" />
|
||||
<Content Include="menus\scenes\menus\options_menu\video\video_options_menu.tscn" />
|
||||
<Content Include="menus\scenes\menus\options_menu\video\video_options_menu_with_extras.tscn" />
|
||||
<Content Include="menus\scenes\opening\opening.gd" />
|
||||
<Content Include="menus\scenes\opening\opening.gd.uid" />
|
||||
<Content Include="menus\scenes\opening\opening.tscn" />
|
||||
<Content Include="menus\scenes\opening\opening_with_logo.tscn" />
|
||||
<Content Include="menus\scenes\overlaid_menus\game_won_menu.gd" />
|
||||
<Content Include="menus\scenes\overlaid_menus\game_won_menu.gd.uid" />
|
||||
<Content Include="menus\scenes\overlaid_menus\game_won_menu.tscn" />
|
||||
<Content Include="menus\scenes\overlaid_menus\level_lost_menu.gd" />
|
||||
<Content Include="menus\scenes\overlaid_menus\level_lost_menu.gd.uid" />
|
||||
<Content Include="menus\scenes\overlaid_menus\level_lost_menu.tscn" />
|
||||
<Content Include="menus\scenes\overlaid_menus\level_won_menu.gd" />
|
||||
<Content Include="menus\scenes\overlaid_menus\level_won_menu.gd.uid" />
|
||||
<Content Include="menus\scenes\overlaid_menus\level_won_menu.tscn" />
|
||||
<Content Include="menus\scenes\overlaid_menus\mini_options_overlaid_menu.tscn" />
|
||||
<Content Include="menus\scenes\overlaid_menus\overlaid_menu.gd" />
|
||||
<Content Include="menus\scenes\overlaid_menus\overlaid_menu.gd.uid" />
|
||||
<Content Include="menus\scenes\overlaid_menus\overlaid_menu.tscn" />
|
||||
<Content Include="menus\scenes\overlaid_menus\overlaid_menu_container.gd" />
|
||||
<Content Include="menus\scenes\overlaid_menus\overlaid_menu_container.gd.uid" />
|
||||
<Content Include="menus\scenes\overlaid_menus\overlaid_menu_container.tscn" />
|
||||
<Content Include="menus\scenes\overlaid_menus\pause_menu.gd" />
|
||||
<Content Include="menus\scenes\overlaid_menus\pause_menu.gd.uid" />
|
||||
<Content Include="menus\scenes\overlaid_menus\pause_menu.tscn" />
|
||||
<Content Include="menus\scripts\game_state.gd" />
|
||||
<Content Include="menus\scripts\game_state.gd.uid" />
|
||||
<Content Include="menus\scripts\level_list_and_state_manager.gd" />
|
||||
<Content Include="menus\scripts\level_list_and_state_manager.gd.uid" />
|
||||
<Content Include="menus\scripts\level_state.gd" />
|
||||
<Content Include="menus\scripts\level_state.gd.uid" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="addons\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="RustyOptions" Version="0.10.1" />
|
||||
</ItemGroup>
|
||||
<!-- gdUnit4 package dependencies -->
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.0"/>
|
||||
<PackageReference Include="gdUnit4.api" Version="5.1.0-rc3"/>
|
||||
<PackageReference Include="gdUnit4.test.adapter" Version="3.0.0"/>
|
||||
<PackageReference Include="gdUnit4.analyzers" Version="1.0.0">
|
||||
<PrivateAssets>none</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1 +1 @@
|
||||
uid://do2c2faoehm61
|
||||
uid://i04mdqgjjfsa
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bretpek2ehht4
|
||||
uid://lcya8t25hn0j
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
name="gdUnit4"
|
||||
description="Unit Testing Framework for Godot Scripts"
|
||||
author="Mike Schulze"
|
||||
version="6.0.3"
|
||||
version="6.1.0"
|
||||
script="plugin.gd"
|
||||
|
||||
@@ -1,23 +1,29 @@
|
||||
@tool
|
||||
extends EditorPlugin
|
||||
|
||||
# We need to define manually the slot id's, to be downwards compatible
|
||||
const CONTEXT_SLOT_FILESYSTEM: int = 1 # EditorContextMenuPlugin.CONTEXT_SLOT_FILESYSTEM
|
||||
const CONTEXT_SLOT_SCRIPT_EDITOR: int = 2 # EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR
|
||||
|
||||
var _gd_inspector: Control
|
||||
var _gd_console: Control
|
||||
var _gd_filesystem_context_menu: Variant
|
||||
var _gd_scripteditor_context_menu: Variant
|
||||
var _filesystem_context_menu: EditorContextMenuPlugin
|
||||
var _editor_context_menu: EditorContextMenuPlugin
|
||||
var _editor_code_context_menu: EditorContextMenuPlugin
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
|
||||
var inferred_declaration: int = ProjectSettings.get_setting("debug/gdscript/warnings/inferred_declaration")
|
||||
var exclude_addons: bool = ProjectSettings.get_setting("debug/gdscript/warnings/exclude_addons")
|
||||
if !exclude_addons and inferred_declaration != 0:
|
||||
|
||||
var is_gdunit_excluded_warnings: bool = false
|
||||
if Engine.get_version_info().hex >= 0x40600:
|
||||
var dirctrory_rules: Dictionary = ProjectSettings.get_setting("debug/gdscript/warnings/directory_rules")
|
||||
if dirctrory_rules.has("res://addons/gdUnit4") and dirctrory_rules["res://addons/gdUnit4"] == 0:
|
||||
is_gdunit_excluded_warnings = true
|
||||
else:
|
||||
is_gdunit_excluded_warnings = ProjectSettings.get_setting("debug/gdscript/warnings/exclude_addons")
|
||||
if !is_gdunit_excluded_warnings and inferred_declaration != 0:
|
||||
printerr("GdUnit4: 'inferred_declaration' is set to Warning/Error!")
|
||||
printerr("GdUnit4 is not 'inferred_declaration' save, you have to excluded addons (debug/gdscript/warnings/exclude_addons)")
|
||||
if Engine.get_version_info().hex >= 0x40600:
|
||||
printerr("GdUnit4 is not 'inferred_declaration' save, you have to excluded the addon (debug/gdscript/warnings/directory_rules)")
|
||||
else:
|
||||
printerr("GdUnit4 is not 'inferred_declaration' save, you have to excluded addons (debug/gdscript/warnings/exclude_addons)")
|
||||
printerr("Loading GdUnit4 Plugin failed.")
|
||||
return
|
||||
|
||||
@@ -73,36 +79,21 @@ func check_running_in_test_env() -> bool:
|
||||
|
||||
|
||||
func _add_context_menus() -> void:
|
||||
if Engine.get_version_info().hex >= 0x40400:
|
||||
# With Godot 4.4 we have to use the 'add_context_menu_plugin' to register editor context menus
|
||||
_gd_filesystem_context_menu = _preload_gdx_script("res://addons/gdUnit4/src/ui/menu/EditorFileSystemContextMenuHandlerV44.gdx")
|
||||
call_deferred("add_context_menu_plugin", CONTEXT_SLOT_FILESYSTEM, _gd_filesystem_context_menu)
|
||||
# the CONTEXT_SLOT_SCRIPT_EDITOR is adding to the script panel instead of script editor see https://github.com/godotengine/godot/pull/100556
|
||||
#_gd_scripteditor_context_menu = _preload("res://addons/gdUnit4/src/ui/menu/ScriptEditorContextMenuHandlerV44.gdx")
|
||||
#call_deferred("add_context_menu_plugin", CONTEXT_SLOT_SCRIPT_EDITOR, _gd_scripteditor_context_menu)
|
||||
# so we use the old hacky way to add the context menu
|
||||
_gd_inspector.add_child(preload("res://addons/gdUnit4/src/ui/menu/ScriptEditorContextMenuHandler.gd").new())
|
||||
else:
|
||||
# TODO Delete it if the minimum requirement for the plugin is set to Godot 4.4.
|
||||
_gd_inspector.add_child(preload("res://addons/gdUnit4/src/ui/menu/EditorFileSystemContextMenuHandler.gd").new())
|
||||
_gd_inspector.add_child(preload("res://addons/gdUnit4/src/ui/menu/ScriptEditorContextMenuHandler.gd").new())
|
||||
_filesystem_context_menu = preload("res://addons/gdUnit4/src/ui/menu/GdUnitEditorFileSystemContextMenuHandler.gd").new()
|
||||
_editor_context_menu = preload("res://addons/gdUnit4/src/ui/menu/GdUnitScriptEditorContextMenuHandler.gd").new()
|
||||
_editor_code_context_menu = preload("res://addons/gdUnit4/src/ui/menu/GdUnitScriptEditorContextMenuHandler.gd").new()
|
||||
add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_FILESYSTEM, _filesystem_context_menu)
|
||||
add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR, _editor_context_menu)
|
||||
add_context_menu_plugin(EditorContextMenuPlugin.CONTEXT_SLOT_SCRIPT_EDITOR_CODE, _editor_code_context_menu)
|
||||
|
||||
|
||||
func _remove_context_menus() -> void:
|
||||
if is_instance_valid(_gd_filesystem_context_menu):
|
||||
call_deferred("remove_context_menu_plugin", _gd_filesystem_context_menu)
|
||||
if is_instance_valid(_gd_scripteditor_context_menu):
|
||||
call_deferred("remove_context_menu_plugin", _gd_scripteditor_context_menu)
|
||||
|
||||
|
||||
func _preload_gdx_script(script_path: String) -> Variant:
|
||||
var script: GDScript = GDScript.new()
|
||||
script.source_code = GdUnitFileAccess.resource_as_string(script_path)
|
||||
script.take_over_path(script_path)
|
||||
var err :Error = script.reload()
|
||||
if err != OK:
|
||||
push_error("Can't create context menu %s, error: %s" % [script_path, error_string(err)])
|
||||
return script.new()
|
||||
if is_instance_valid(_filesystem_context_menu):
|
||||
remove_context_menu_plugin(_filesystem_context_menu)
|
||||
if is_instance_valid(_editor_context_menu):
|
||||
remove_context_menu_plugin(_editor_context_menu)
|
||||
if is_instance_valid(_editor_code_context_menu):
|
||||
remove_context_menu_plugin(_editor_code_context_menu)
|
||||
|
||||
|
||||
func _on_resource_saved(resource: Resource) -> void:
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bc4fimf6ynr5d
|
||||
uid://8wxua8uw7x7k
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://buiskkw1yyuw3
|
||||
uid://duj13ipuced2q
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://drfioswpw8u2u
|
||||
uid://wd2ydmpylh1e
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://byeulsiqvaugq
|
||||
uid://bwaeyokx1kgfd
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bmy2nu4w22wia
|
||||
uid://qqwrtj2mj3xi
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://c1jp2le4lldby
|
||||
uid://fnv7o85xbiiq
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bftfpffmfb1il
|
||||
uid://bav21rax06rdf
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dkap7kpfh2bhg
|
||||
uid://b750alnjl31nv
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://8s1lymhdvlpu
|
||||
uid://cfqx4148ov21q
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://x54vf4fue301
|
||||
uid://hqhd4a063x3n
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://vt1hx0i6pg4h
|
||||
uid://xsowfqnkhk7j
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://l487wamffax1
|
||||
uid://crdh3ctgqxrqi
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bvvptcdhi1g14
|
||||
uid://bqguqoaa43uev
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bwkv3a1hhdt88
|
||||
uid://clve38xv30uem
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://ghuy35olsym1
|
||||
uid://chqkkjclq101n
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dmunl8xg53sym
|
||||
uid://b7mk5mihqqr65
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://b4n45twg8y2ar
|
||||
uid://cgee6csuvo1ye
|
||||
|
||||
@@ -24,9 +24,8 @@ extends RefCounted
|
||||
|
||||
|
||||
## Simulates that a key has been pressed.[br]
|
||||
## @deprecated: the modifier [b]shift_pressed[/b] and [b]ctrl_pressed[/b] will be removed in v7.0
|
||||
## [member key_code] : the key code e.g. [constant KEY_ENTER][br]
|
||||
## [member shift_pressed] : false by default set to true if simmulate shift is press[br]
|
||||
## [member ctrl_pressed] : false by default set to true if simmulate control is press[br]
|
||||
## [codeblock]
|
||||
## func test_key_presssed():
|
||||
## var runner = scene_runner("res://scenes/simple_scene.tscn")
|
||||
@@ -35,17 +34,43 @@ extends RefCounted
|
||||
@abstract func simulate_key_pressed(key_code: int, shift_pressed := false, ctrl_pressed := false) -> GdUnitSceneRunner
|
||||
|
||||
|
||||
## Simulates that a key is pressed.[br]
|
||||
## Simulates that a key is pressing.[br]
|
||||
## @deprecated: the modifier [b]shift_pressed[/b] and [b]ctrl_pressed[/b] will be removed in v7.0[br]See `test_key_shift_and_A_presssing` for example using key combinations
|
||||
## [member key_code] : the key code e.g. [constant KEY_ENTER][br]
|
||||
## [member shift_pressed] : false by default set to true if simmulate shift is press[br]
|
||||
## [member ctrl_pressed] : false by default set to true if simmulate control is press[br]
|
||||
## [codeblock]
|
||||
## # Do simulate key pressing A
|
||||
## func test_key_A_presssing():
|
||||
## var runner = scene_runner("res://scenes/simple_scene.tscn")
|
||||
## await runner.simulate_key_press(KEY_A)
|
||||
##
|
||||
##
|
||||
## # Do simulate keycombination pressing shift+A
|
||||
## func test_key_shift_and_A_presssing():
|
||||
## var runner = scene_runner("res://scenes/simple_scene.tscn")
|
||||
## runner.simulate_key_press(KEY_SHIFT)
|
||||
## runner.simulate_key_press(KEY_A)
|
||||
## await _runner.await_input_processed()
|
||||
## [/codeblock]
|
||||
@abstract func simulate_key_press(key_code: int, shift_pressed := false, ctrl_pressed := false) -> GdUnitSceneRunner
|
||||
|
||||
|
||||
## Simulates that a key has been released.[br]
|
||||
## [member key_code] : the key code e.g. [constant KEY_ENTER][br]
|
||||
## [member shift_pressed] : false by default set to true if simmulate shift is press[br]
|
||||
## [member ctrl_pressed] : false by default set to true if simmulate control is press[br]
|
||||
## [codeblock]
|
||||
## # Do simulate releasing key A
|
||||
## func test_key_A_releasing():
|
||||
## var runner = scene_runner("res://scenes/simple_scene.tscn")
|
||||
## await runner.simulate_key_release(KEY_A)
|
||||
##
|
||||
##
|
||||
## # Do simulate keycombination pressing shift+A
|
||||
## func test_key_shift_and_A_releasing(():
|
||||
## var runner = scene_runner("res://scenes/simple_scene.tscn")
|
||||
## runner.simulate_key_release(KEY_SHIFT)
|
||||
## runner.simulate_key_release(KEY_A)
|
||||
## await _runner.await_input_processed()
|
||||
## [/codeblock]
|
||||
## @deprecated: the modifier [b]shift_pressed[/b] and [b]ctrl_pressed[/b] will be removed in v7.0[br]See `test_key_shift_and_A_releasing` for example using key combinations
|
||||
@abstract func simulate_key_release(key_code: int, shift_pressed := false, ctrl_pressed := false) -> GdUnitSceneRunner
|
||||
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dn20c5e8kb3q3
|
||||
uid://cg867wakih43u
|
||||
|
||||
@@ -27,20 +27,132 @@ extends GdUnitAssert
|
||||
@abstract func append_failure_message(message: String) -> GdUnitSignalAssert
|
||||
|
||||
|
||||
## Verifies that given signal is emitted until waiting time
|
||||
@abstract func is_emitted(name: String, args := []) -> GdUnitSignalAssert
|
||||
## Verifies that the specified signal is emitted with the expected arguments.[br]
|
||||
##
|
||||
## This assertion waits for a signal to be emitted from the object under test and
|
||||
## validates that it was emitted with the correct arguments. The function supports
|
||||
## both typed signals (Signal type) and string-based signal names for flexibility
|
||||
## in different testing scenarios.[br]
|
||||
## [br]
|
||||
## [b]Parameters:[/b][br]
|
||||
## [param signal_name]: The signal to monitor. Can be either:[br]
|
||||
## • A [Signal] reference (recommended for type safety)[br]
|
||||
## • A [String] with the signal name
|
||||
## [param signal_args]: Optional expected signal arguments.[br]
|
||||
## When provided, verifies the signal was emitted with exactly these values.[br]
|
||||
## [br]
|
||||
## [b]Returns:[/b][br]
|
||||
## [GdUnitSignalAssert] - Returns self for method chaining.[br]
|
||||
## [br]
|
||||
## [b]Examples:[/b]
|
||||
## [codeblock]
|
||||
## signal signal_a(value: int)
|
||||
## signal signal_b(name: String, count: int)
|
||||
##
|
||||
## # Wait for signal emission without checking arguments
|
||||
## # Using Signal reference (type-safe)
|
||||
## await assert_signal(instance).is_emitted(signal_a)
|
||||
## # Using string name (dynamic)
|
||||
## await assert_signal(instance).is_emitted("signal_a")
|
||||
##
|
||||
## # Wait for signal emission with specific argument
|
||||
## await assert_signal(instance).is_emitted(signal_a, 10)
|
||||
##
|
||||
## # Wait for signal with multiple arguments
|
||||
## await assert_signal(instance).is_emitted(signal_b, "test", 42)
|
||||
##
|
||||
## # Wait max 500ms for signal with argument 10
|
||||
## await assert_signal(instance).wait_until(500).is_emitted(signal_a, 10)
|
||||
## [/codeblock]
|
||||
## [br]
|
||||
## [b]Note:[/b] This is an async operation - use [code]await[/code] when calling.[br]
|
||||
## The assertion fails if the signal is not emitted within the timeout period.
|
||||
@abstract func is_emitted(signal_name: Variant, ...signal_args: Array) -> GdUnitSignalAssert
|
||||
|
||||
|
||||
## Verifies that given signal is NOT emitted until waiting time
|
||||
@abstract func is_not_emitted(name: String, args := []) -> GdUnitSignalAssert
|
||||
## Verifies that the specified signal is NOT emitted with the expected arguments.[br]
|
||||
##
|
||||
## This assertion waits for a specified time period and validates that a signal
|
||||
## was not emitted with the given arguments. Useful for ensuring certain conditions
|
||||
## don't trigger unwanted signals or for verifying signal filtering logic.[br]
|
||||
## [br]
|
||||
## [b]Parameters:[/b][br]
|
||||
## [param signal_name]: The signal to monitor. Can be either:[br]
|
||||
## • A [Signal] reference (recommended for type safety)[br]
|
||||
## • A [String] with the signal name
|
||||
## [param signal_args]: Optional expected signal arguments.[br]
|
||||
## When provided, verifies the signal was not emitted with these specific values.[br]
|
||||
## If omitted, verifies the signal was not emitted at all.[br]
|
||||
## [br]
|
||||
## [b]Returns:[/b][br]
|
||||
## [GdUnitSignalAssert] - Returns self for method chaining.[br]
|
||||
## [br]
|
||||
## [b]Examples:[/b]
|
||||
## [codeblock]
|
||||
## signal signal_a(value: int)
|
||||
## signal signal_b(name: String, count: int)
|
||||
##
|
||||
## # Verify signal is not emitted at all (without checking arguments)
|
||||
## await assert_signal(instance).wait_until(500).is_not_emitted(signal_a)
|
||||
## await assert_signal(instance).wait_until(500).is_not_emitted("signal_a")
|
||||
##
|
||||
## # Verify signal is not emitted with specific argument
|
||||
## await assert_signal(instance).wait_until(500).is_not_emitted(signal_a, 10)
|
||||
##
|
||||
## # Verify signal is not emitted with multiple arguments
|
||||
## await assert_signal(instance).wait_until(500).is_not_emitted(signal_b, "test", 42)
|
||||
##
|
||||
## # Can be emitted with different arguments (this passes)
|
||||
## instance.emit_signal("signal_a", 20) # Emits with 20, not 10
|
||||
## await assert_signal(instance).wait_until(500).is_not_emitted(signal_a, 10)
|
||||
## [/codeblock]
|
||||
## [br]
|
||||
## [b]Note:[/b] This is an async operation - use [code]await[/code] when calling.[br]
|
||||
## The assertion fails if the signal IS emitted with the specified arguments within the timeout period.
|
||||
@abstract func is_not_emitted(signal_name: Variant, ...signal_args: Array) -> GdUnitSignalAssert
|
||||
|
||||
|
||||
## Verifies the signal exists checked the emitter
|
||||
@abstract func is_signal_exists(name: String) -> GdUnitSignalAssert
|
||||
## Verifies that the specified signal exists on the emitter object.[br]
|
||||
##
|
||||
## This assertion checks if a signal is defined on the object under test,
|
||||
## regardless of whether it has been emitted. Useful for validating that
|
||||
## objects have the expected signals before testing their emission.[br]
|
||||
## [br]
|
||||
## [b]Parameters:[/b][br]
|
||||
## [param signal_name]: The signal to check. Can be either:[br]
|
||||
## • A [Signal] reference (recommended for type safety)[br]
|
||||
## • A [String] with the signal name
|
||||
## [br]
|
||||
## [b]Returns:[/b][br]
|
||||
## [GdUnitSignalAssert] - Returns self for method chaining.[br]
|
||||
## [br]
|
||||
## [b]Examples:[/b]
|
||||
## [codeblock]
|
||||
## signal my_signal(value: int)
|
||||
## signal another_signal()
|
||||
##
|
||||
## # Verify signal exists using Signal reference
|
||||
## assert_signal(instance).is_signal_exists(my_signal)
|
||||
##
|
||||
## # Verify signal exists using string name
|
||||
## assert_signal(instance).is_signal_exists("my_signal")
|
||||
##
|
||||
## # Chain with other assertions
|
||||
## assert_signal(instance) \
|
||||
## .is_signal_exists(my_signal) \
|
||||
## .is_emitted(my_signal, 42)
|
||||
##
|
||||
## [/codeblock]
|
||||
## [br]
|
||||
## [b]Note:[/b] This only checks signal definition, not emission.[br]
|
||||
## The assertion fails if the signal is not defined on the object.
|
||||
@abstract func is_signal_exists(signal_name: Variant) -> GdUnitSignalAssert
|
||||
|
||||
|
||||
## Sets the assert signal timeout in ms, if the time over a failure is reported.[br]
|
||||
## e.g.[br]
|
||||
## Example:
|
||||
## [codeblock]
|
||||
## do wait until 5s the instance has emitted the signal `signal_a`[br]
|
||||
## [code]assert_signal(instance).wait_until(5000).is_emitted("signal_a")[/code]
|
||||
## assert_signal(instance).wait_until(5000).is_emitted("signal_a")
|
||||
## [/codeblock]
|
||||
@abstract func wait_until(timeout: int) -> GdUnitSignalAssert
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://572nse6u4l86
|
||||
uid://ck4dbwhcpf144
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://ip241g801xri
|
||||
uid://b2itt4pwvweqo
|
||||
|
||||
@@ -14,14 +14,13 @@
|
||||
class_name GdUnitTestSuite
|
||||
extends Node
|
||||
|
||||
const NO_ARG :Variant = GdUnitConstants.NO_ARG
|
||||
|
||||
### internal runtime variables that must not be overwritten!!!
|
||||
@warning_ignore("unused_private_class_variable")
|
||||
var __is_skipped := false
|
||||
@warning_ignore("unused_private_class_variable")
|
||||
var __skip_reason :String = "Unknow."
|
||||
var __active_test_case :String
|
||||
var __skip_reason := "Unknow."
|
||||
var __active_test_case: String
|
||||
var __awaiter := __gdunit_awaiter()
|
||||
|
||||
|
||||
@@ -29,7 +28,7 @@ var __awaiter := __gdunit_awaiter()
|
||||
### in order to noticeably reduce the loading time of the test suite.
|
||||
# We go this hard way to increase the loading performance to avoid reparsing all the used scripts
|
||||
# for more detailed info -> https://github.com/godotengine/godot/issues/67400
|
||||
func __lazy_load(script_path :String) -> GDScript:
|
||||
func __lazy_load(script_path: String) -> GDScript:
|
||||
return GdUnitAssertions.__lazy_load(script_path)
|
||||
|
||||
|
||||
@@ -81,23 +80,23 @@ func after_test() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func is_failure(_expected_failure :String = NO_ARG) -> bool:
|
||||
func is_failure() -> bool:
|
||||
return Engine.get_meta("GD_TEST_FAILURE") if Engine.has_meta("GD_TEST_FAILURE") else false
|
||||
|
||||
|
||||
func set_active_test_case(test_case :String) -> void:
|
||||
func set_active_test_case(test_case: String) -> void:
|
||||
__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/class_@globalscope.html#enum-globalscope-error
|
||||
func error_as_string(error_number :int) -> String:
|
||||
func error_as_string(error_number: int) -> String:
|
||||
return error_string(error_number)
|
||||
|
||||
|
||||
## A litle helper to auto freeing your created objects after test execution
|
||||
func auto_free(obj :Variant) -> Variant:
|
||||
func auto_free(obj: Variant) -> Variant:
|
||||
var execution_context := GdUnitThreadManager.get_current_context().get_execution_context()
|
||||
|
||||
assert(execution_context != null, "INTERNAL ERROR: The current execution_context is null! Please report this as bug.")
|
||||
@@ -105,7 +104,7 @@ func auto_free(obj :Variant) -> Variant:
|
||||
|
||||
|
||||
@warning_ignore("native_method_override")
|
||||
func add_child(node :Node, force_readable_name := false, internal := Node.INTERNAL_MODE_DISABLED) -> void:
|
||||
func add_child(node: Node, force_readable_name := false, internal := Node.INTERNAL_MODE_DISABLED) -> void:
|
||||
super.add_child(node, force_readable_name, internal)
|
||||
var execution_context := GdUnitThreadManager.get_current_context().get_execution_context()
|
||||
if execution_context != null:
|
||||
@@ -123,7 +122,7 @@ func discard_error_interupted_by_timeout() -> void:
|
||||
## Creates a new directory under the temporary directory *user://tmp*[br]
|
||||
## Useful for storing data during test execution. [br]
|
||||
## The directory is automatically deleted after test suite execution
|
||||
func create_temp_dir(relative_path :String) -> String:
|
||||
func create_temp_dir(relative_path: String) -> String:
|
||||
@warning_ignore("unsafe_method_access")
|
||||
return __gdunit_file_access().create_temp_dir(relative_path)
|
||||
|
||||
@@ -138,25 +137,25 @@ func clean_temp_dir() -> void:
|
||||
## Creates a new file under the temporary directory *user://tmp* + <relative_path>[br]
|
||||
## with given name <file_name> and given file <mode> (default = File.WRITE)[br]
|
||||
## If success the returned File is automatically closed after the execution of the test suite
|
||||
func create_temp_file(relative_path :String, file_name :String, mode := FileAccess.WRITE) -> FileAccess:
|
||||
func create_temp_file(relative_path: String, file_name: String, mode := FileAccess.WRITE) -> FileAccess:
|
||||
@warning_ignore("unsafe_method_access")
|
||||
return __gdunit_file_access().create_temp_file(relative_path, file_name, mode)
|
||||
|
||||
|
||||
## Reads a resource by given path <resource_path> into a PackedStringArray.
|
||||
func resource_as_array(resource_path :String) -> PackedStringArray:
|
||||
func resource_as_array(resource_path: String) -> PackedStringArray:
|
||||
@warning_ignore("unsafe_method_access")
|
||||
return __gdunit_file_access().resource_as_array(resource_path)
|
||||
|
||||
|
||||
## Reads a resource by given path <resource_path> and returned the content as String.
|
||||
func resource_as_string(resource_path :String) -> String:
|
||||
func resource_as_string(resource_path: String) -> String:
|
||||
@warning_ignore("unsafe_method_access")
|
||||
return __gdunit_file_access().resource_as_string(resource_path)
|
||||
|
||||
|
||||
## Reads a resource by given path <resource_path> and return Variand translated by str_to_var
|
||||
func resource_as_var(resource_path :String) -> Variant:
|
||||
func resource_as_var(resource_path: String) -> Variant:
|
||||
@warning_ignore("unsafe_method_access", "unsafe_cast")
|
||||
return str_to_var(__gdunit_file_access().resource_as_string(resource_path) as String)
|
||||
|
||||
@@ -166,7 +165,7 @@ func resource_as_var(resource_path :String) -> Variant:
|
||||
## signal_name: signal name[br]
|
||||
## args: the expected signal arguments as an array[br]
|
||||
## timeout: the timeout in ms, default is set to 2000ms
|
||||
func await_signal_on(source :Object, signal_name :String, args :Array = [], timeout :int = 2000) -> Variant:
|
||||
func await_signal_on(source: Object, signal_name: String, args: Array = [], timeout: int = 2000) -> Variant:
|
||||
@warning_ignore("unsafe_method_access")
|
||||
return await __awaiter.await_signal_on(source, signal_name, args, timeout)
|
||||
|
||||
@@ -184,11 +183,50 @@ func await_idle_frame() -> void:
|
||||
## await await_millis(myNode, 100).completed
|
||||
## [/codeblock][br]
|
||||
## use this waiter and not `await get_tree().create_timer().timeout to prevent errors when a test case is timed out
|
||||
func await_millis(timeout :int) -> void:
|
||||
func await_millis(timeout: int) -> void:
|
||||
@warning_ignore("unsafe_method_access")
|
||||
await __awaiter.await_millis(timeout)
|
||||
|
||||
|
||||
## Collects detailed information about orphaned nodes for debugging purposes.[br]
|
||||
##
|
||||
## This function gathers comprehensive details about nodes that remain in memory
|
||||
## after test execution (orphans). It provides debugging information to help
|
||||
## identify the source of memory leaks in tests. Must be manually called in
|
||||
## tests when orphan nodes are detected.[br]
|
||||
## [br]
|
||||
## [b]When to Use:[/b][br]
|
||||
## - When GdUnit4 reports orphan nodes after test execution[br]
|
||||
## - For debugging memory leaks in test scenarios[br]
|
||||
## - To get detailed information about unreleased nodes[br]
|
||||
## [br]
|
||||
## [b]Usage Pattern:[/b][br]
|
||||
## Add this call at the end of tests that are suspected to create orphans,
|
||||
## or when the test runner reports orphan detection.[br]
|
||||
## [br]
|
||||
## [b]Examples:[/b]
|
||||
## [codeblock]
|
||||
## func test_scene_management():
|
||||
## # Test code that might create orphan nodes
|
||||
## var scene = preload("res://TestScene.tscn").instantiate()
|
||||
## add_child(scene)
|
||||
##
|
||||
## # Do test operations
|
||||
## scene.some_method()
|
||||
##
|
||||
## # Clean up (but might miss some nodes)
|
||||
## scene.queue_free()
|
||||
##
|
||||
## # Collect orphan details if any are detected
|
||||
## collect_orphan_node_details()
|
||||
## [/codeblock]
|
||||
## [br]
|
||||
## [b]Note:[/b] This is a debugging utility function that should be removed
|
||||
## or commented out once orphan issues are resolved.
|
||||
func collect_orphan_node_details() -> void:
|
||||
GdUnitThreadManager.get_current_context().get_execution_context().orphan_monitor_collect()
|
||||
|
||||
|
||||
## Creates a new scene runner to allow simulate interactions checked a scene.[br]
|
||||
## The runner will manage the scene instance and release after the runner is released[br]
|
||||
## example:[br]
|
||||
@@ -200,7 +238,7 @@ func await_millis(timeout :int) -> void:
|
||||
## # or simply creates a runner by using the scene resource path
|
||||
## var runner := scene_runner("res://foo/my_scne.tscn")
|
||||
## [/codeblock]
|
||||
func scene_runner(scene :Variant, verbose := false) -> GdUnitSceneRunner:
|
||||
func scene_runner(scene: Variant, verbose := false) -> GdUnitSceneRunner:
|
||||
return auto_free(__lazy_load("res://addons/gdUnit4/src/core/GdUnitSceneRunnerImpl.gd").new(scene, verbose))
|
||||
|
||||
|
||||
@@ -216,13 +254,13 @@ const RETURN_DEEP_STUB = GdUnitMock.RETURN_DEEP_STUB
|
||||
|
||||
|
||||
## Creates a mock for given class name
|
||||
func mock(clazz :Variant, mock_mode := RETURN_DEFAULTS) -> Variant:
|
||||
func mock(clazz: Variant, mock_mode := RETURN_DEFAULTS) -> Variant:
|
||||
@warning_ignore("unsafe_method_access")
|
||||
return __lazy_load("res://addons/gdUnit4/src/mocking/GdUnitMockBuilder.gd").build(clazz, mock_mode)
|
||||
|
||||
|
||||
## Creates a spy checked given object instance
|
||||
func spy(instance :Variant) -> Variant:
|
||||
func spy(instance: Variant) -> Variant:
|
||||
@warning_ignore("unsafe_method_access")
|
||||
return __lazy_load("res://addons/gdUnit4/src/spy/GdUnitSpyBuilder.gd").build(instance)
|
||||
|
||||
@@ -233,30 +271,30 @@ func spy(instance :Variant) -> Variant:
|
||||
## # overrides the return value of myMock.is_selected() to false
|
||||
## do_return(false).on(myMock).is_selected()
|
||||
## [/codeblock]
|
||||
func do_return(value :Variant) -> GdUnitMock:
|
||||
func do_return(value: Variant) -> GdUnitMock:
|
||||
return GdUnitMock.new(value)
|
||||
|
||||
|
||||
## Verifies certain behavior happened at least once or exact number of times
|
||||
func verify(obj :Variant, times := 1) -> Variant:
|
||||
func verify(obj: Variant, times := 1) -> Variant:
|
||||
@warning_ignore("unsafe_method_access")
|
||||
return __gdunit_object_interactions().verify(obj, times)
|
||||
|
||||
|
||||
## Verifies no interactions is happen checked this mock or spy
|
||||
func verify_no_interactions(obj :Variant) -> GdUnitAssert:
|
||||
func verify_no_interactions(obj: Variant) -> GdUnitAssert:
|
||||
@warning_ignore("unsafe_method_access")
|
||||
return __gdunit_object_interactions().verify_no_interactions(obj)
|
||||
|
||||
|
||||
## Verifies the given mock or spy has any unverified interaction.
|
||||
func verify_no_more_interactions(obj :Variant) -> GdUnitAssert:
|
||||
func verify_no_more_interactions(obj: Variant) -> GdUnitAssert:
|
||||
@warning_ignore("unsafe_method_access")
|
||||
return __gdunit_object_interactions().verify_no_more_interactions(obj)
|
||||
|
||||
|
||||
## Resets the saved function call counters checked a mock or spy
|
||||
func reset(obj :Variant) -> void:
|
||||
func reset(obj: Variant) -> void:
|
||||
@warning_ignore("unsafe_method_access")
|
||||
__gdunit_object_interactions().reset(obj)
|
||||
|
||||
@@ -273,7 +311,7 @@ func reset(obj :Variant) -> void:
|
||||
## # verify the signial is emitted
|
||||
## await assert_signal(emitter).is_emitted('my_signal')
|
||||
## [/codeblock]
|
||||
func monitor_signals(source :Object, _auto_free := true) -> Object:
|
||||
func monitor_signals(source: Object, _auto_free := true) -> Object:
|
||||
@warning_ignore("unsafe_method_access")
|
||||
__lazy_load("res://addons/gdUnit4/src/core/thread/GdUnitThreadManager.gd")\
|
||||
.get_current_context()\
|
||||
@@ -502,29 +540,46 @@ func any_class(clazz :Object) -> GdUnitArgumentMatcher:
|
||||
|
||||
# === value extract utils ======================================================
|
||||
## Builds an extractor by given function name and optional arguments
|
||||
func extr(func_name :String, args := Array()) -> GdUnitValueExtractor:
|
||||
func extr(func_name: String, args := Array()) -> GdUnitValueExtractor:
|
||||
return __lazy_load("res://addons/gdUnit4/src/extractors/GdUnitFuncValueExtractor.gd").new(func_name, args)
|
||||
|
||||
|
||||
## Constructs a tuple by given arguments
|
||||
func tuple(arg0 :Variant,
|
||||
arg1 :Variant=NO_ARG,
|
||||
arg2 :Variant=NO_ARG,
|
||||
arg3 :Variant=NO_ARG,
|
||||
arg4 :Variant=NO_ARG,
|
||||
arg5 :Variant=NO_ARG,
|
||||
arg6 :Variant=NO_ARG,
|
||||
arg7 :Variant=NO_ARG,
|
||||
arg8 :Variant=NO_ARG,
|
||||
arg9 :Variant=NO_ARG) -> GdUnitTuple:
|
||||
return GdUnitTuple.new(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
||||
## Creates a GdUnitTuple from the provided arguments for use in test assertions.
|
||||
## [br]
|
||||
## This is the primary helper function for creating tuples in GdUnit4 tests.
|
||||
## It provides a convenient way to group multiple expected values when using
|
||||
## [method extractv] assertions. The function enforces that tuples must contain
|
||||
## at least two values, as single-value extractions don't require tuple grouping.
|
||||
## [br]
|
||||
## [b]Parameters:[/b] [br]
|
||||
## - [code]...args[/code]: Variable number of arguments (minimum 2) to group into a tuple.
|
||||
## Each argument represents a value to be compared in assertions.
|
||||
## [br]
|
||||
## [b]Returns:[/b] [br]
|
||||
## A [GdUnitTuple] containing the provided values, or an empty tuple if fewer than
|
||||
## 2 arguments are provided (with an error message).
|
||||
## [br]
|
||||
## [b]Error Handling:[/b] [br]
|
||||
## [codeblock]
|
||||
## # This will push an error and return empty tuple
|
||||
## var invalid = tuple("single_value") # Error: requires at least 2 arguments
|
||||
## [br]
|
||||
## # Correct usage - minimum 2 arguments
|
||||
## var valid = tuple("name", "value")
|
||||
## var valid_multi = tuple(1, 2, 3, 4, 5) # Can have many values
|
||||
## [/codeblock]
|
||||
func tuple(...args: Array) -> GdUnitTuple:
|
||||
if args.size() < 2:
|
||||
push_error("Tuple requires at least two arguments.")
|
||||
return GdUnitTuple.new()
|
||||
return GdUnitTuple.new.callv(args)
|
||||
|
||||
|
||||
# === Asserts ==================================================================
|
||||
|
||||
## The common assertion tool to verify values.
|
||||
## It checks the given value by type to fit to the best assert
|
||||
func assert_that(current :Variant) -> GdUnitAssert:
|
||||
func assert_that(current: Variant) -> GdUnitAssert:
|
||||
match typeof(current):
|
||||
TYPE_BOOL:
|
||||
return assert_bool(current)
|
||||
@@ -549,22 +604,22 @@ func assert_that(current :Variant) -> GdUnitAssert:
|
||||
|
||||
|
||||
## An assertion tool to verify boolean values.
|
||||
func assert_bool(current :Variant) -> GdUnitBoolAssert:
|
||||
func assert_bool(current: Variant) -> GdUnitBoolAssert:
|
||||
return __lazy_load("res://addons/gdUnit4/src/asserts/GdUnitBoolAssertImpl.gd").new(current)
|
||||
|
||||
|
||||
## An assertion tool to verify String values.
|
||||
func assert_str(current :Variant) -> GdUnitStringAssert:
|
||||
func assert_str(current: Variant) -> GdUnitStringAssert:
|
||||
return __lazy_load("res://addons/gdUnit4/src/asserts/GdUnitStringAssertImpl.gd").new(current)
|
||||
|
||||
|
||||
## An assertion tool to verify integer values.
|
||||
func assert_int(current :Variant) -> GdUnitIntAssert:
|
||||
func assert_int(current: Variant) -> GdUnitIntAssert:
|
||||
return __lazy_load("res://addons/gdUnit4/src/asserts/GdUnitIntAssertImpl.gd").new(current)
|
||||
|
||||
|
||||
## An assertion tool to verify float values.
|
||||
func assert_float(current :Variant) -> GdUnitFloatAssert:
|
||||
func assert_float(current: Variant) -> GdUnitFloatAssert:
|
||||
return __lazy_load("res://addons/gdUnit4/src/asserts/GdUnitFloatAssertImpl.gd").new(current)
|
||||
|
||||
|
||||
@@ -574,41 +629,41 @@ func assert_float(current :Variant) -> GdUnitFloatAssert:
|
||||
## [codeblock]
|
||||
## assert_vector(Vector2(1.2, 1.000001)).is_equal(Vector2(1.2, 1.000001))
|
||||
## [/codeblock]
|
||||
func assert_vector(current :Variant, type_check := true) -> GdUnitVectorAssert:
|
||||
func assert_vector(current: Variant, type_check := true) -> GdUnitVectorAssert:
|
||||
return __lazy_load("res://addons/gdUnit4/src/asserts/GdUnitVectorAssertImpl.gd").new(current, type_check)
|
||||
|
||||
|
||||
## An assertion tool to verify arrays.
|
||||
func assert_array(current :Variant, type_check := true) -> GdUnitArrayAssert:
|
||||
func assert_array(current: Variant, type_check := true) -> GdUnitArrayAssert:
|
||||
return __lazy_load("res://addons/gdUnit4/src/asserts/GdUnitArrayAssertImpl.gd").new(current, type_check)
|
||||
|
||||
|
||||
## An assertion tool to verify dictionaries.
|
||||
func assert_dict(current :Variant) -> GdUnitDictionaryAssert:
|
||||
func assert_dict(current: Variant) -> GdUnitDictionaryAssert:
|
||||
return __lazy_load("res://addons/gdUnit4/src/asserts/GdUnitDictionaryAssertImpl.gd").new(current)
|
||||
|
||||
|
||||
## An assertion tool to verify FileAccess.
|
||||
func assert_file(current :Variant) -> GdUnitFileAssert:
|
||||
func assert_file(current: Variant) -> GdUnitFileAssert:
|
||||
return __lazy_load("res://addons/gdUnit4/src/asserts/GdUnitFileAssertImpl.gd").new(current)
|
||||
|
||||
|
||||
## An assertion tool to verify Objects.
|
||||
func assert_object(current :Variant) -> GdUnitObjectAssert:
|
||||
func assert_object(current: Variant) -> GdUnitObjectAssert:
|
||||
return __lazy_load("res://addons/gdUnit4/src/asserts/GdUnitObjectAssertImpl.gd").new(current)
|
||||
|
||||
|
||||
func assert_result(current :Variant) -> GdUnitResultAssert:
|
||||
func assert_result(current: Variant) -> GdUnitResultAssert:
|
||||
return __lazy_load("res://addons/gdUnit4/src/asserts/GdUnitResultAssertImpl.gd").new(current)
|
||||
|
||||
|
||||
## An assertion tool that waits until a certain time for an expected function return value
|
||||
func assert_func(instance :Object, func_name :String, args := Array()) -> GdUnitFuncAssert:
|
||||
func assert_func(instance: Object, func_name: String, args := Array()) -> GdUnitFuncAssert:
|
||||
return __lazy_load("res://addons/gdUnit4/src/asserts/GdUnitFuncAssertImpl.gd").new(instance, func_name, args)
|
||||
|
||||
|
||||
## An assertion tool to verify for emitted signals until a certain time.
|
||||
func assert_signal(instance :Object) -> GdUnitSignalAssert:
|
||||
func assert_signal(instance: Object) -> GdUnitSignalAssert:
|
||||
return __lazy_load("res://addons/gdUnit4/src/asserts/GdUnitSignalAssertImpl.gd").new(instance)
|
||||
|
||||
|
||||
@@ -619,7 +674,7 @@ func assert_signal(instance :Object) -> GdUnitSignalAssert:
|
||||
## assert_failure(func(): assert_bool(true).is_not_equal(true)) \
|
||||
## .has_message("Expecting:\n 'true'\n not equal to\n 'true'")
|
||||
## [/codeblock]
|
||||
func assert_failure(assertion :Callable) -> GdUnitFailureAssert:
|
||||
func assert_failure(assertion: Callable) -> GdUnitFailureAssert:
|
||||
@warning_ignore("unsafe_method_access")
|
||||
return __lazy_load("res://addons/gdUnit4/src/asserts/GdUnitFailureAssertImpl.gd").new().execute(assertion)
|
||||
|
||||
@@ -631,7 +686,7 @@ func assert_failure(assertion :Callable) -> GdUnitFailureAssert:
|
||||
## await assert_failure_await(func(): assert_bool(true).is_not_equal(true)) \
|
||||
## .has_message("Expecting:\n 'true'\n not equal to\n 'true'")
|
||||
## [/codeblock]
|
||||
func assert_failure_await(assertion :Callable) -> GdUnitFailureAssert:
|
||||
func assert_failure_await(assertion: Callable) -> GdUnitFailureAssert:
|
||||
@warning_ignore("unsafe_method_access")
|
||||
return await __lazy_load("res://addons/gdUnit4/src/asserts/GdUnitFailureAssertImpl.gd").new().execute_and_await(assertion)
|
||||
|
||||
@@ -648,7 +703,7 @@ func assert_failure_await(assertion :Callable) -> GdUnitFailureAssert:
|
||||
## await assert_error(func (): push_error('test error') )\
|
||||
## .is_push_error('test error')
|
||||
## [/codeblock]
|
||||
func assert_error(current :Callable) -> GdUnitGodotErrorAssert:
|
||||
func assert_error(current: Callable) -> GdUnitGodotErrorAssert:
|
||||
return __lazy_load("res://addons/gdUnit4/src/asserts/GdUnitGodotErrorAssertImpl.gd").new(current)
|
||||
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://cgbfa4cflb5nl
|
||||
uid://bfroomur047su
|
||||
|
||||
@@ -1,28 +1,86 @@
|
||||
## A tuple implementation to hold two or many values
|
||||
## A tuple implementation for GdUnit4 test assertions and value extraction.
|
||||
## @tutorial(GdUnit4 Array Assertions): https://mikeschulze.github.io/gdUnit4/latest/testing/assert-array/#extractv
|
||||
## @tutorial(GdUnit4 Testing Framework): https://mikeschulze.github.io/gdUnit4/
|
||||
## [br]
|
||||
## The GdUnitTuple class is a utility container designed specifically for the GdUnit4
|
||||
## testing framework. It enables advanced assertion operations, particularly when
|
||||
## extracting and comparing multiple values from complex test results.
|
||||
## [br]
|
||||
## [b]Primary Use Cases in Testing:[/b] [br]
|
||||
## - Extracting multiple properties from test objects with [method extractv]## [br]
|
||||
## - Grouping related assertion values for comparison## [br]
|
||||
## - Returning multiple values from test helper methods## [br]
|
||||
## - Organizing expected vs actual value pairs in assertions## [br]
|
||||
## [br]
|
||||
## [b]Example Usage in Tests:[/b]
|
||||
## [codeblock]
|
||||
## func test_player_stats_after_level_up():
|
||||
## var player = Player.new()
|
||||
## player.level_up()
|
||||
##
|
||||
## # Extract multiple properties using tuple
|
||||
## assert_array([player]) \
|
||||
## .extractv(extr("name"), extr("level"), extr("hp")) \
|
||||
## .contains(tuple("Hero", 2, 150))
|
||||
##
|
||||
## func test_enemy_spawn_positions():
|
||||
## var enemies: Array = spawn_enemies(3)
|
||||
##
|
||||
## # Verify multiple enemies have correct position data
|
||||
## assert_array(enemies) \
|
||||
## .extractv(extr("position.x"), extr("position.y")) \
|
||||
## .contains_exactly([
|
||||
## tuple(100, 200),
|
||||
## tuple(150, 200),
|
||||
## tuple(200, 200)
|
||||
## ])
|
||||
## [/codeblock]
|
||||
## [br]
|
||||
## [b]Integration with GdUnit4 Assertions:[/b] [br]
|
||||
## Tuples work seamlessly with array assertion methods like: [br]
|
||||
## - [code]contains()[/code] - Check if extracted values contain specific tuples [br]
|
||||
## - [code]contains_exactly()[/code] - Verify exact tuple matches [br]
|
||||
## - [code]is_equal()[/code] - Compare tuple equality [br]
|
||||
## [br]
|
||||
## [b]Note:[/b] This class is part of the GdUnit4 testing framework's internal
|
||||
## utilities and is primarily intended for use within test assertions rather
|
||||
## than production code.
|
||||
class_name GdUnitTuple
|
||||
extends RefCounted
|
||||
|
||||
const NO_ARG :Variant = GdUnitConstants.NO_ARG
|
||||
|
||||
var __values :Array = Array()
|
||||
var _values: Array = []
|
||||
|
||||
|
||||
func _init(arg0:Variant,
|
||||
arg1 :Variant=NO_ARG,
|
||||
arg2 :Variant=NO_ARG,
|
||||
arg3 :Variant=NO_ARG,
|
||||
arg4 :Variant=NO_ARG,
|
||||
arg5 :Variant=NO_ARG,
|
||||
arg6 :Variant=NO_ARG,
|
||||
arg7 :Variant=NO_ARG,
|
||||
arg8 :Variant=NO_ARG,
|
||||
arg9 :Variant=NO_ARG) -> void:
|
||||
__values = GdArrayTools.filter_value([arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9], NO_ARG)
|
||||
## Initializes a new GdUnitTuple with test values.
|
||||
## [br]
|
||||
## Creates a tuple to hold multiple values extracted from test objects
|
||||
## or expected values for assertions. Commonly used with the [code]tuple()[/code]
|
||||
## helper function in GdUnit4 tests.
|
||||
## [br]
|
||||
## [b]Parameters:[/b]
|
||||
## - [code]...args[/code]: Variable number of values to store.
|
||||
func _init(...args: Array) -> void:
|
||||
_values = args
|
||||
|
||||
|
||||
## Returns the tuple's values as an array for assertion comparisons.
|
||||
## [br]
|
||||
## Provides access to the stored test values. Used internally by GdUnit4's
|
||||
## assertion system when comparing tuples in test validations.
|
||||
## [br]
|
||||
## [b]Returns:[/b]
|
||||
## An [Array] containing all values stored in the tuple.
|
||||
func values() -> Array:
|
||||
return __values
|
||||
return _values
|
||||
|
||||
|
||||
## Returns a string representation for test output and debugging.
|
||||
## [br]
|
||||
## Formats the tuple for display in test results, error messages, and debug logs.
|
||||
## This method is automatically called by GdUnit4 when displaying assertion
|
||||
## failures involving tuples.
|
||||
## [br]
|
||||
## [b]Returns:[/b]
|
||||
## A [String] in the format "tuple([value1, value2, ...])"
|
||||
func _to_string() -> String:
|
||||
return "tuple(%s)" % str(__values)
|
||||
return "tuple(%s)" % str(_values)
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://mjqw2uww51fk
|
||||
uid://ckj5nn4gln5bw
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://2dylh01qtb66
|
||||
uid://cyagv2phlu24d
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bcx6bgypklb3e
|
||||
uid://hrk46nhl8icp
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://r43u2usutiss
|
||||
uid://bymqibokrfyuk
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://coauynw7rnsij
|
||||
uid://bxkxeyj2jbth2
|
||||
|
||||
@@ -40,22 +40,40 @@ static func input_event_as_text(event :InputEvent) -> String:
|
||||
var text := ""
|
||||
if event is InputEventKey:
|
||||
var key_event := event as InputEventKey
|
||||
text += "InputEventKey : key='%s', pressed=%s, keycode=%d, physical_keycode=%s" % [
|
||||
event.as_text(), key_event.pressed, key_event.keycode, key_event.physical_keycode]
|
||||
text += """
|
||||
InputEventKey : keycode=%s (%s) pressed: %s
|
||||
physical_keycode: %s
|
||||
location: %s
|
||||
echo: %s""" % [
|
||||
key_event.keycode,
|
||||
event.as_text_keycode(),
|
||||
key_event.pressed,
|
||||
key_event.physical_keycode,
|
||||
key_event.location,
|
||||
key_event.echo]
|
||||
else:
|
||||
text += event.as_text()
|
||||
if event is InputEventMouse:
|
||||
var mouse_event := event as InputEventMouse
|
||||
text += ", global_position %s" % mouse_event.global_position
|
||||
text += """
|
||||
global_position: %s""" % mouse_event.global_position
|
||||
if event is InputEventWithModifiers:
|
||||
var mouse_event := event as InputEventWithModifiers
|
||||
text += ", shift=%s, alt=%s, control=%s, meta=%s, command=%s" % [
|
||||
text += """
|
||||
--------
|
||||
mods: %s
|
||||
shift: %s
|
||||
alt: %s
|
||||
control: %s
|
||||
meta: %s
|
||||
command: %s""" % [
|
||||
mouse_event.get_modifiers_mask(),
|
||||
mouse_event.shift_pressed,
|
||||
mouse_event.alt_pressed,
|
||||
mouse_event.ctrl_pressed,
|
||||
mouse_event.meta_pressed,
|
||||
mouse_event.command_or_control_autoremap]
|
||||
return text
|
||||
return text.dedent()
|
||||
|
||||
|
||||
static func _colored_string_div(characters: String) -> String:
|
||||
@@ -119,6 +137,10 @@ static func _nerror(number :Variant) -> String:
|
||||
return "[color=%s]%s[/color]" % [ERROR_COLOR, str(number)]
|
||||
|
||||
|
||||
static func _colored(value: Variant, color: Color) -> String:
|
||||
return "[color=%s]%s[/color]" % [color.to_html(), value]
|
||||
|
||||
|
||||
static func _colored_value(value :Variant) -> String:
|
||||
match typeof(value):
|
||||
TYPE_STRING, TYPE_STRING_NAME:
|
||||
@@ -161,19 +183,53 @@ static func _index_report_as_table(index_reports :Array) -> String:
|
||||
return table.replace("$cells", cells)
|
||||
|
||||
|
||||
static func orphan_detected_on_suite_setup(count :int) -> String:
|
||||
return "%s\n Detected <%d> orphan nodes during test suite setup stage! [b]Check before() and after()![/b]" % [
|
||||
_warning("WARNING:"), count]
|
||||
|
||||
static func orphan_warning(orphans_count: int) -> String:
|
||||
return """
|
||||
%s: Found %s possible orphan nodes.
|
||||
Add %s to the end of the test to collect details.""".dedent().trim_prefix("\n") % [
|
||||
_warning("WARNING:"),
|
||||
_nerror(orphans_count),
|
||||
_colored_value("collect_orphan_node_details()")
|
||||
]
|
||||
|
||||
static func orphan_detected_on_suite_setup(orphans: Array[GdUnitOrphanNodeInfo]) -> String:
|
||||
return """
|
||||
%s Detected %s orphan nodes!
|
||||
[b]Verify your test suite setup.[/b]
|
||||
%s""".dedent().trim_prefix("\n") % [
|
||||
_warning("WARNING:"),
|
||||
_nerror(orphans.size()),
|
||||
_build_orphan_node_stacktrace(orphans)]
|
||||
|
||||
|
||||
static func orphan_detected_on_test_setup(count :int) -> String:
|
||||
return "%s\n Detected <%d> orphan nodes during test setup! [b]Check before_test() and after_test()![/b]" % [
|
||||
_warning("WARNING:"), count]
|
||||
static func orphan_detected_on_test_setup(orphans: Array[GdUnitOrphanNodeInfo]) -> String:
|
||||
return """
|
||||
%s Detected %s orphan nodes on test setup!
|
||||
[b]Check before_test() and after_test()![/b]
|
||||
%s""".dedent().trim_prefix("\n") % [
|
||||
_warning("WARNING:"),
|
||||
_nerror(orphans.size()),
|
||||
_build_orphan_node_stacktrace(orphans)
|
||||
]
|
||||
|
||||
|
||||
static func orphan_detected_on_test(count :int) -> String:
|
||||
return "%s\n Detected <%d> orphan nodes during test execution!" % [
|
||||
_warning("WARNING:"), count]
|
||||
static func orphan_detected_on_test(orphans: Array[GdUnitOrphanNodeInfo]) -> String:
|
||||
return """
|
||||
%s Detected %s orphan nodes!
|
||||
%s""".dedent().trim_prefix("\n") % [
|
||||
_warning("WARNING:"),
|
||||
_nerror(orphans.size()),
|
||||
_build_orphan_node_stacktrace(orphans)
|
||||
]
|
||||
|
||||
|
||||
static func _build_orphan_node_stacktrace(orphans: Array[GdUnitOrphanNodeInfo]) -> String:
|
||||
var stack_trace := "\n"
|
||||
for orphan in orphans:
|
||||
stack_trace += orphan.as_trace(orphan, true) + "\n"
|
||||
return stack_trace.indent(" ")
|
||||
|
||||
|
||||
|
||||
static func fuzzer_interuped(iterations: int, error: String) -> String:
|
||||
@@ -188,6 +244,10 @@ static func test_timeout(timeout :int) -> String:
|
||||
return "%s\n %s" % [_error("Timeout !"), _colored_value("Test timed out after %s" % LocalTime.elapsed(timeout))]
|
||||
|
||||
|
||||
static func test_session_terminated() -> String:
|
||||
return "%s" % _error("Test Session Terminated")
|
||||
|
||||
|
||||
# gdlint:disable = mixed-tabs-and-spaces
|
||||
static func test_suite_skipped(hint :String, skip_count :int) -> String:
|
||||
return """
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://vl7cfc01g5wl
|
||||
uid://c178wdncle4i5
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://brxvavm3ml0om
|
||||
uid://5fthlxduiurg
|
||||
|
||||
@@ -75,7 +75,7 @@ func _toPackedStringArray(value: Variant) -> PackedStringArray:
|
||||
return PackedStringArray([str(value)])
|
||||
|
||||
|
||||
func _array_equals_div(current: Variant, expected: Variant, case_sensitive: bool = false) -> Array[Array]:
|
||||
func _array_equals_div(current: Variant, expected: Variant, case_sensitive: bool = false) -> Array:
|
||||
var current_value := _toPackedStringArray(current)
|
||||
var expected_value := _toPackedStringArray(expected)
|
||||
var index_report := Array()
|
||||
@@ -374,24 +374,12 @@ func extractv(...extractors: Array) -> GdUnitArrayAssert:
|
||||
_current_value_provider = DefaultValueProvider.new(null)
|
||||
else:
|
||||
for element: Variant in current:
|
||||
var ev: Array[Variant] = [
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG,
|
||||
GdUnitTuple.NO_ARG
|
||||
]
|
||||
|
||||
var ev: Array[Variant] = []
|
||||
for index: int in extractors.size():
|
||||
var extractor: GdUnitValueExtractor = extractors[index]
|
||||
ev[index] = extractor.extract_value(element)
|
||||
ev.append(extractor.extract_value(element))
|
||||
if extractors.size() > 1:
|
||||
extracted_elements.append(GdUnitTuple.new(ev[0], ev[1], ev[2], ev[3], ev[4], ev[5], ev[6], ev[7], ev[8], ev[9]))
|
||||
extracted_elements.append(GdUnitTuple.new.callv(ev))
|
||||
else:
|
||||
extracted_elements.append(ev[0])
|
||||
_current_value_provider = DefaultValueProvider.new(extracted_elements)
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bx7cehfdh2x4w
|
||||
uid://381c6r7r5uhp
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://cq38mcld2thyl
|
||||
uid://8c05oepulju5
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://61d7pdgldg0r
|
||||
uid://crrhhudfmy3ay
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://cxndss6mdq7de
|
||||
uid://c310wp8sog1ti
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dqrp7csbeyvon
|
||||
uid://diqntuiv0y7pg
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://cbrj7dsr235i0
|
||||
uid://b8htynygoyy0f
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://2s6h0titid8y
|
||||
uid://dg0uusgasnr64
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dvce6xeybbh1i
|
||||
uid://fyb32t5gwdxk
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://c2jdw0vv5nldq
|
||||
uid://bd15pn72awek1
|
||||
|
||||
@@ -4,6 +4,7 @@ var _current_failure_message := ""
|
||||
var _custom_failure_message := ""
|
||||
var _additional_failure_message := ""
|
||||
var _callable: Callable
|
||||
var _logger := GodotGdErrorMonitor.new()
|
||||
|
||||
|
||||
func _init(callable: Callable) -> void:
|
||||
@@ -14,17 +15,10 @@ func _init(callable: Callable) -> void:
|
||||
|
||||
|
||||
func _execute() -> Array[ErrorLogEntry]:
|
||||
# execute the given code and monitor for runtime errors
|
||||
if _callable == null or not _callable.is_valid():
|
||||
@warning_ignore("return_value_discarded")
|
||||
_report_error("Invalid Callable '%s'" % _callable)
|
||||
else:
|
||||
await _callable.call()
|
||||
return await _error_monitor().scan(true)
|
||||
|
||||
|
||||
func _error_monitor() -> GodotGdErrorMonitor:
|
||||
return GdUnitThreadManager.get_current_context().get_execution_context().error_monitor
|
||||
_logger.start()
|
||||
await _callable.call()
|
||||
_logger.stop()
|
||||
return _logger.log_entries()
|
||||
|
||||
|
||||
func failure_message() -> String:
|
||||
@@ -46,8 +40,6 @@ func _report_error(error_message: String, failure_line_number: int = -1) -> GdUn
|
||||
func _has_log_entry(log_entries: Array[ErrorLogEntry], type: ErrorLogEntry.TYPE, error: Variant) -> bool:
|
||||
for entry in log_entries:
|
||||
if entry._type == type and GdObjects.equals(entry._message, error):
|
||||
# Erase the log entry we already handled it by this assertion, otherwise it will report at twice
|
||||
_error_monitor().erase_log_entry(entry)
|
||||
return true
|
||||
return false
|
||||
|
||||
@@ -55,12 +47,11 @@ func _has_log_entry(log_entries: Array[ErrorLogEntry], type: ErrorLogEntry.TYPE,
|
||||
func _to_list(log_entries: Array[ErrorLogEntry]) -> String:
|
||||
if log_entries.is_empty():
|
||||
return "no errors"
|
||||
if log_entries.size() == 1:
|
||||
return log_entries[0]._message
|
||||
var value := ""
|
||||
|
||||
var values := []
|
||||
for entry in log_entries:
|
||||
value += "'%s'\n" % entry._message
|
||||
return value
|
||||
values.append(entry)
|
||||
return "\n".join(values)
|
||||
|
||||
|
||||
func is_null() -> GdUnitGodotErrorAssert:
|
||||
@@ -90,6 +81,9 @@ func append_failure_message(message: String) -> GdUnitGodotErrorAssert:
|
||||
|
||||
|
||||
func is_success() -> GdUnitGodotErrorAssert:
|
||||
if not _validate_callable():
|
||||
return self
|
||||
|
||||
var log_entries := await _execute()
|
||||
if log_entries.is_empty():
|
||||
return _report_success()
|
||||
@@ -100,6 +94,9 @@ func is_success() -> GdUnitGodotErrorAssert:
|
||||
|
||||
|
||||
func is_runtime_error(expected_error: Variant) -> GdUnitGodotErrorAssert:
|
||||
if not _validate_callable():
|
||||
return self
|
||||
|
||||
var result := GdUnitArgumentMatchers.is_variant_string_matching(expected_error)
|
||||
if result.is_error():
|
||||
return _report_error(result.error_message())
|
||||
@@ -108,12 +105,15 @@ func is_runtime_error(expected_error: Variant) -> GdUnitGodotErrorAssert:
|
||||
return _report_success()
|
||||
return _report_error("""
|
||||
Expecting: a runtime error is triggered.
|
||||
message: '%s'
|
||||
found: %s
|
||||
expected: '%s'
|
||||
current: '%s'
|
||||
""".dedent().trim_prefix("\n") % [expected_error, _to_list(log_entries)])
|
||||
|
||||
|
||||
func is_push_warning(expected_warning: Variant) -> GdUnitGodotErrorAssert:
|
||||
if not _validate_callable():
|
||||
return self
|
||||
|
||||
var result := GdUnitArgumentMatchers.is_variant_string_matching(expected_warning)
|
||||
if result.is_error():
|
||||
return _report_error(result.error_message())
|
||||
@@ -122,12 +122,15 @@ func is_push_warning(expected_warning: Variant) -> GdUnitGodotErrorAssert:
|
||||
return _report_success()
|
||||
return _report_error("""
|
||||
Expecting: push_warning() is called.
|
||||
message: '%s'
|
||||
found: %s
|
||||
expected: '%s'
|
||||
current: '%s'
|
||||
""".dedent().trim_prefix("\n") % [expected_warning, _to_list(log_entries)])
|
||||
|
||||
|
||||
func is_push_error(expected_error: Variant) -> GdUnitGodotErrorAssert:
|
||||
if not _validate_callable():
|
||||
return self
|
||||
|
||||
var result := GdUnitArgumentMatchers.is_variant_string_matching(expected_error)
|
||||
if result.is_error():
|
||||
return _report_error(result.error_message())
|
||||
@@ -136,6 +139,14 @@ func is_push_error(expected_error: Variant) -> GdUnitGodotErrorAssert:
|
||||
return _report_success()
|
||||
return _report_error("""
|
||||
Expecting: push_error() is called.
|
||||
message: '%s'
|
||||
found: %s
|
||||
expected: '%s'
|
||||
current: '%s'
|
||||
""".dedent().trim_prefix("\n") % [expected_error, _to_list(log_entries)])
|
||||
|
||||
|
||||
func _validate_callable() -> bool:
|
||||
if _callable == null or not _callable.is_valid():
|
||||
@warning_ignore("return_value_discarded")
|
||||
_report_error("Invalid Callable '%s'" % _callable)
|
||||
return false
|
||||
return true
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://cyi6ooahncq7q
|
||||
uid://d3st26kcndm8l
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://j4mpmwm2hw61
|
||||
uid://bcuh7lnvrg7mb
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bm6qm58a0dacq
|
||||
uid://ba515a8xk0ubo
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://b0dlq6jyjcvps
|
||||
uid://dwl5ooagjg2nc
|
||||
|
||||
@@ -91,7 +91,11 @@ func is_not_equal(_expected: Variant) -> GdUnitSignalAssert:
|
||||
|
||||
|
||||
# Verifies the signal exists checked the emitter
|
||||
func is_signal_exists(signal_name :String) -> GdUnitSignalAssert:
|
||||
func is_signal_exists(signal_name: Variant) -> GdUnitSignalAssert:
|
||||
if not (signal_name is String or signal_name is Signal):
|
||||
return report_error("Invalid signal_name: expected String or Signal, but is '%s'" % type_string(typeof(signal_name)))
|
||||
signal_name = (signal_name as Signal).get_name() if signal_name is Signal else signal_name
|
||||
|
||||
if not _emitter.has_signal(signal_name):
|
||||
@warning_ignore("return_value_discarded")
|
||||
report_error("The signal '%s' not exists checked object '%s'." % [signal_name, _emitter.get_class()])
|
||||
@@ -99,20 +103,36 @@ func is_signal_exists(signal_name :String) -> GdUnitSignalAssert:
|
||||
|
||||
|
||||
# Verifies that given signal is emitted until waiting time
|
||||
func is_emitted(name :String, args := []) -> GdUnitSignalAssert:
|
||||
func is_emitted(signal_name: Variant, ...signal_args: Array) -> GdUnitSignalAssert:
|
||||
_line_number = GdUnitAssertions.get_line_number()
|
||||
return await _wail_until_signal(name, args, false)
|
||||
return await _wail_until_signal(
|
||||
signal_name,
|
||||
_wrap_arguments.callv(signal_args),
|
||||
false)
|
||||
|
||||
|
||||
# Verifies that given signal is NOT emitted until waiting time
|
||||
func is_not_emitted(name :String, args := []) -> GdUnitSignalAssert:
|
||||
func is_not_emitted(signal_name: Variant, ...signal_args: Array) -> GdUnitSignalAssert:
|
||||
_line_number = GdUnitAssertions.get_line_number()
|
||||
return await _wail_until_signal(name, args, true)
|
||||
return await _wail_until_signal(
|
||||
signal_name,
|
||||
_wrap_arguments.callv(signal_args),
|
||||
true)
|
||||
|
||||
|
||||
func _wail_until_signal(signal_name :String, expected_args :Array, expect_not_emitted: bool) -> GdUnitSignalAssert:
|
||||
func _wrap_arguments(...args: Array) -> Array:
|
||||
# Check using old syntax
|
||||
if not args.is_empty() and args[0] is Array:
|
||||
return args[0]
|
||||
return args
|
||||
|
||||
|
||||
func _wail_until_signal(signal_value: Variant, expected_args: Array, expect_not_emitted: bool) -> GdUnitSignalAssert:
|
||||
if _emitter == null:
|
||||
return report_error("Can't wait for signal checked a NULL object.")
|
||||
if not (signal_value is String or signal_value is Signal):
|
||||
return report_error("Invalid signal_name: expected String or Signal, but is '%s'" % type_string(typeof(signal_value)))
|
||||
var signal_name := (signal_value as Signal).get_name() if signal_value is Signal else signal_value
|
||||
# first verify the signal is defined
|
||||
if not _emitter.has_signal(signal_name):
|
||||
return report_error("Can't wait for non-existion signal '%s' checked object '%s'." % [signal_name,_emitter.get_class()])
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dlh37yc086vr5
|
||||
uid://c3ytdhnam8ba7
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dxqvilchqqeta
|
||||
uid://cw5h1gecccd37
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://r4avfcakvscw
|
||||
uid://pyvt1oi43853
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://8y15b6ts3kss
|
||||
uid://beueufp3wgjw8
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://d4hd3vc50jltg
|
||||
uid://34eyejb3x15x
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://w4mr1j0k0l
|
||||
uid://crpirtbbekydy
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://ccm3ivfiaf3i7
|
||||
uid://dbbsj4qqi8w3m
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://ccnb2ah35atho
|
||||
uid://cpokylwutgxw6
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://0p8udx4tdwol
|
||||
uid://swuykw4qh2xx
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bk60ywsj4ekp7
|
||||
uid://etq75dot1c03
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://b5sli0lem5xca
|
||||
uid://cx8bp6vsxyrts
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://b7ldhc4ryfh1v
|
||||
uid://dk4tv55wf5mlm
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bbaqjhpbxce3u
|
||||
uid://ds3n71e8n4wce
|
||||
|
||||
@@ -196,7 +196,7 @@ static func resource_as_string(resource_path :String) -> String:
|
||||
if file == null:
|
||||
push_error("ERROR: Can't read resource '%s'. %s" % [resource_path, error_string(FileAccess.get_open_error())])
|
||||
return ""
|
||||
return file.get_as_text(true)
|
||||
return file.get_as_text()
|
||||
|
||||
|
||||
static func make_qualified_path(path :String) -> String:
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dflqb5germp5n
|
||||
uid://ddr26lg6f055n
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://cqndh0nuu8ltx
|
||||
uid://c0ymnlx3jooyl
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://cnvq3nb61ei76
|
||||
uid://b6k1ufvw6w2s5
|
||||
|
||||
@@ -18,7 +18,10 @@ var _config := {
|
||||
TESTS : Array([], TYPE_OBJECT, "RefCounted", GdUnitTestCase),
|
||||
|
||||
# the port of running test server for this session
|
||||
SERVER_PORT : -1
|
||||
SERVER_PORT : -1,
|
||||
|
||||
# Exit on first failure
|
||||
EXIT_FAIL_FAST : false
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +43,15 @@ func server_port() -> int:
|
||||
return _config.get(SERVER_PORT, -1)
|
||||
|
||||
|
||||
func do_fail_fast(is_fail_fast: bool) -> GdUnitRunnerConfig:
|
||||
_config[EXIT_FAIL_FAST] = is_fail_fast
|
||||
return self
|
||||
|
||||
|
||||
func is_fail_fast() -> bool:
|
||||
return _config.get(EXIT_FAIL_FAST, false)
|
||||
|
||||
|
||||
func add_test_cases(tests: Array[GdUnitTestCase]) -> GdUnitRunnerConfig:
|
||||
test_cases().append_array(tests)
|
||||
return self
|
||||
@@ -57,7 +69,8 @@ func save_config(path: String = CONFIG_FILE) -> GdUnitResult:
|
||||
|
||||
var to_save := {
|
||||
VERSION : CONFIG_VERSION,
|
||||
SERVER_PORT : _config.get(SERVER_PORT),
|
||||
EXIT_FAIL_FAST : is_fail_fast(),
|
||||
SERVER_PORT : server_port(),
|
||||
TESTS : Array()
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://ltvpkh3ayklf
|
||||
uid://dvrxtyni1604f
|
||||
|
||||
@@ -72,12 +72,11 @@ func _init(p_scene: Variant, p_verbose: bool, p_hide_push_errors := false) -> vo
|
||||
return
|
||||
|
||||
_scene_tree().root.add_child(_current_scene)
|
||||
Engine.set_meta("GdUnitSceneRunner", self)
|
||||
# do finally reset all open input events when the scene is removed
|
||||
@warning_ignore("return_value_discarded")
|
||||
_scene_tree().root.child_exiting_tree.connect(func f(child :Node) -> void:
|
||||
_scene_tree().root.child_exiting_tree.connect(func f(child: Node) -> void:
|
||||
if child == _current_scene:
|
||||
# we need to disable the processing to avoid input flush buffer errors
|
||||
_current_scene.process_mode = Node.PROCESS_MODE_DISABLED
|
||||
_reset_input_to_default()
|
||||
)
|
||||
_simulate_start_time = LocalTime.now()
|
||||
@@ -103,6 +102,7 @@ func _notification(what: int) -> void:
|
||||
_current_scene.free()
|
||||
_is_disposed = true
|
||||
_current_scene = null
|
||||
Engine.remove_meta("GdUnitSceneRunner")
|
||||
|
||||
|
||||
func _scene_tree() -> SceneTree:
|
||||
@@ -145,6 +145,7 @@ func simulate_action_release(action: String, event_index := -1) -> GdUnitSceneRu
|
||||
|
||||
@warning_ignore("return_value_discarded")
|
||||
func simulate_key_pressed(key_code: int, shift_pressed := false, ctrl_pressed := false) -> GdUnitSceneRunner:
|
||||
_push_warning_deprecated_arguments(shift_pressed, ctrl_pressed)
|
||||
simulate_key_press(key_code, shift_pressed, ctrl_pressed)
|
||||
await _scene_tree().process_frame
|
||||
simulate_key_release(key_code, shift_pressed, ctrl_pressed)
|
||||
@@ -152,30 +153,33 @@ func simulate_key_pressed(key_code: int, shift_pressed := false, ctrl_pressed :=
|
||||
|
||||
|
||||
func simulate_key_press(key_code: int, shift_pressed := false, ctrl_pressed := false) -> GdUnitSceneRunner:
|
||||
_push_warning_deprecated_arguments(shift_pressed, ctrl_pressed)
|
||||
__print_current_focus()
|
||||
var event := InputEventKey.new()
|
||||
event.pressed = true
|
||||
event.keycode = key_code as Key
|
||||
event.physical_keycode = key_code as Key
|
||||
event.unicode = key_code
|
||||
event.alt_pressed = key_code == KEY_ALT
|
||||
event.shift_pressed = shift_pressed or key_code == KEY_SHIFT
|
||||
event.ctrl_pressed = ctrl_pressed or key_code == KEY_CTRL
|
||||
event.set_alt_pressed(key_code == KEY_ALT)
|
||||
event.set_shift_pressed(shift_pressed)
|
||||
event.set_ctrl_pressed(ctrl_pressed)
|
||||
event.get_modifiers_mask()
|
||||
_apply_input_modifiers(event)
|
||||
_key_on_press.append(key_code)
|
||||
return _handle_input_event(event)
|
||||
|
||||
|
||||
func simulate_key_release(key_code: int, shift_pressed := false, ctrl_pressed := false) -> GdUnitSceneRunner:
|
||||
_push_warning_deprecated_arguments(shift_pressed, ctrl_pressed)
|
||||
__print_current_focus()
|
||||
var event := InputEventKey.new()
|
||||
event.pressed = false
|
||||
event.keycode = key_code as Key
|
||||
event.physical_keycode = key_code as Key
|
||||
event.unicode = key_code
|
||||
event.alt_pressed = key_code == KEY_ALT
|
||||
event.shift_pressed = shift_pressed or key_code == KEY_SHIFT
|
||||
event.ctrl_pressed = ctrl_pressed or key_code == KEY_CTRL
|
||||
event.set_alt_pressed(key_code == KEY_ALT)
|
||||
event.set_shift_pressed(shift_pressed)
|
||||
event.set_ctrl_pressed(ctrl_pressed)
|
||||
_apply_input_modifiers(event)
|
||||
_key_on_press.erase(key_code)
|
||||
return _handle_input_event(event)
|
||||
@@ -485,6 +489,8 @@ func find_child(name: String, recursive: bool = true, owned: bool = false) -> No
|
||||
|
||||
|
||||
func _scene_name() -> String:
|
||||
if scene() == null:
|
||||
return "unknown"
|
||||
var scene_script :GDScript = scene().get_script()
|
||||
var scene_name :String = scene().get_name()
|
||||
if not scene_script:
|
||||
@@ -515,6 +521,13 @@ func _apply_input_modifiers(event: InputEvent) -> void:
|
||||
_event.ctrl_pressed = _event.ctrl_pressed or last_input_event.ctrl_pressed
|
||||
# this line results into reset the control_pressed state!!!
|
||||
#event.command_or_control_autoremap = event.command_or_control_autoremap or _last_input_event.command_or_control_autoremap
|
||||
if _last_input_event is InputEventKey and event is InputEventWithModifiers:
|
||||
var last_input_event := _last_input_event as InputEventKey
|
||||
var _event := event as InputEventWithModifiers
|
||||
_event.shift_pressed = _event.shift_pressed or last_input_event.keycode == KEY_SHIFT
|
||||
_event.alt_pressed = _event.alt_pressed or last_input_event.keycode == KEY_ALT
|
||||
_event.ctrl_pressed = _event.ctrl_pressed or last_input_event.keycode == KEY_CTRL
|
||||
_event.meta_pressed = _event.meta_pressed or last_input_event.keycode == KEY_META
|
||||
|
||||
|
||||
# copy over current active mouse mask and combine with curren mask
|
||||
@@ -620,3 +633,10 @@ func scene() -> Node:
|
||||
if not _is_disposed:
|
||||
push_error("The current scene instance is not valid anymore! check your test is valid. e.g. check for missing awaits.")
|
||||
return null
|
||||
|
||||
|
||||
func _push_warning_deprecated_arguments(shift_pressed: bool, ctrl_pressed: bool) -> void:
|
||||
if shift_pressed:
|
||||
push_warning("Deprecated! Don't use 'shift_pressed' it will be removed in v7.0, checkout the documentaion how to use key combinations.")
|
||||
if ctrl_pressed:
|
||||
push_warning("Deprecated! Don't use 'ctrl_pressed' it will be removed in v7.0, checkout the documentaion how to use key combinations.")
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://7a566a4kfreu
|
||||
uid://bdhmqovuioydb
|
||||
|
||||
@@ -21,6 +21,7 @@ const TEST_SUITE_NAMING_CONVENTION = GROUP_TEST + "/test_suite_naming_convention
|
||||
const TEST_DISCOVER_ENABLED = GROUP_TEST + "/test_discovery"
|
||||
const TEST_FLAKY_CHECK = GROUP_TEST + "/flaky_check_enable"
|
||||
const TEST_FLAKY_MAX_RETRIES = GROUP_TEST + "/flaky_max_retries"
|
||||
const TEST_RERUN_UNTIL_FAILURE_RETRIES = GROUP_TEST + "/rerun_until_failure_retries"
|
||||
|
||||
|
||||
# Report Setiings
|
||||
@@ -62,6 +63,7 @@ const SHORTCUT_INSPECTOR_RERUN_TEST = GROUP_SHORTCUT_INSPECTOR + "/rerun_test"
|
||||
const SHORTCUT_INSPECTOR_RERUN_TEST_DEBUG = GROUP_SHORTCUT_INSPECTOR + "/rerun_test_debug"
|
||||
const SHORTCUT_INSPECTOR_RUN_TEST_OVERALL = GROUP_SHORTCUT_INSPECTOR + "/run_test_overall"
|
||||
const SHORTCUT_INSPECTOR_RUN_TEST_STOP = GROUP_SHORTCUT_INSPECTOR + "/run_test_stop"
|
||||
const SHORTCUT_INSPECTOR_RERUN_TEST_UNTIL_FAILURE = GROUP_SHORTCUT_INSPECTOR + "/rerun_test_until_failure"
|
||||
|
||||
const GROUP_SHORTCUT_EDITOR = SHORTCUT_SETTINGS + "/editor"
|
||||
const SHORTCUT_EDITOR_RUN_TEST = GROUP_SHORTCUT_EDITOR + "/run_test"
|
||||
@@ -112,6 +114,7 @@ static func setup() -> void:
|
||||
create_property_if_need(TEST_DISCOVER_ENABLED, false, "Automatically detect new tests in test lookup folders at runtime")
|
||||
create_property_if_need(TEST_FLAKY_CHECK, false, "Rerun tests on failure and mark them as FLAKY")
|
||||
create_property_if_need(TEST_FLAKY_MAX_RETRIES, 3, "Sets the number of retries for rerunning a flaky test")
|
||||
create_property_if_need(TEST_RERUN_UNTIL_FAILURE_RETRIES, 10, "The number of reruns until the test fails.")
|
||||
# report settings
|
||||
create_property_if_need(REPORT_PUSH_ERRORS, false, "Report push_error() as failure")
|
||||
create_property_if_need(REPORT_SCRIPT_ERRORS, true, "Report script errors as failure")
|
||||
@@ -148,6 +151,7 @@ static func create_shortcut_properties_if_need() -> void:
|
||||
# inspector
|
||||
create_property_if_need(SHORTCUT_INSPECTOR_RERUN_TEST, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.RERUN_TESTS), "Rerun the most recently executed tests")
|
||||
create_property_if_need(SHORTCUT_INSPECTOR_RERUN_TEST_DEBUG, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.RERUN_TESTS_DEBUG), "Rerun the most recently executed tests (Debug mode)")
|
||||
create_property_if_need(SHORTCUT_INSPECTOR_RERUN_TEST_UNTIL_FAILURE, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.RERUN_TESTS_UNTIL_FAILURE), "Rerun tests until failure occurs")
|
||||
create_property_if_need(SHORTCUT_INSPECTOR_RUN_TEST_OVERALL, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.RUN_TESTS_OVERALL), "Runs all tests (Debug mode)")
|
||||
create_property_if_need(SHORTCUT_INSPECTOR_RUN_TEST_STOP, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.STOP_TEST_RUN), "Stop the current test execution")
|
||||
# script editor
|
||||
@@ -155,8 +159,8 @@ static func create_shortcut_properties_if_need() -> void:
|
||||
create_property_if_need(SHORTCUT_EDITOR_RUN_TEST_DEBUG, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.RUN_TESTCASE_DEBUG), "Run the currently selected test (Debug mode).")
|
||||
create_property_if_need(SHORTCUT_EDITOR_CREATE_TEST, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.CREATE_TEST), "Create a new test case for the currently selected function")
|
||||
# filesystem
|
||||
create_property_if_need(SHORTCUT_FILESYSTEM_RUN_TEST, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.NONE), "Run all test suites in the selected folder or file")
|
||||
create_property_if_need(SHORTCUT_FILESYSTEM_RUN_TEST_DEBUG, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.NONE), "Run all test suites in the selected folder or file (Debug)")
|
||||
create_property_if_need(SHORTCUT_FILESYSTEM_RUN_TEST, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.RUN_TESTSUITE), "Run all test suites in the selected folder or file")
|
||||
create_property_if_need(SHORTCUT_FILESYSTEM_RUN_TEST_DEBUG, GdUnitShortcut.default_keys(GdUnitShortcut.ShortCut.RUN_TESTSUITE_DEBUG), "Run all test suites in the selected folder or file (Debug)")
|
||||
|
||||
|
||||
static func create_property_if_need(name :String, default :Variant, help :="", value_set := PackedStringArray()) -> void:
|
||||
@@ -306,6 +310,10 @@ static func get_flaky_max_retries() -> int:
|
||||
return get_setting(TEST_FLAKY_MAX_RETRIES, 3)
|
||||
|
||||
|
||||
static func get_rerun_max_retries() -> int:
|
||||
return get_setting(TEST_RERUN_UNTIL_FAILURE_RETRIES, 10)
|
||||
|
||||
|
||||
static func set_test_discover_enabled(enable :bool) -> void:
|
||||
var property := get_property(TEST_DISCOVER_ENABLED)
|
||||
property.set_value(enable)
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://coby4unvmd3eh
|
||||
uid://djrx6fy3w3bb
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://ckx5jnr3ip6vp
|
||||
uid://l1nsecnjoon6
|
||||
|
||||
@@ -107,7 +107,7 @@ func is_signal_collecting(emitter: Object, signal_name: String) -> bool:
|
||||
return _collected_signals.has(emitter) and (_collected_signals[emitter] as Dictionary).has(signal_name)
|
||||
|
||||
|
||||
func match(emitter :Object, signal_name :String, args :Array) -> bool:
|
||||
func match(emitter: Object, signal_name: String, args: Array) -> bool:
|
||||
#prints("match", signal_name, _collected_signals[emitter][signal_name]);
|
||||
if _collected_signals.is_empty() or not _collected_signals.has(emitter):
|
||||
return false
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://cm0rbs8vhdhd1
|
||||
uid://bnvdsssykfaeh
|
||||
|
||||
@@ -33,9 +33,9 @@ signal gdunit_client_connected(client_id: int)
|
||||
signal gdunit_client_disconnected(client_id: int)
|
||||
|
||||
|
||||
## Emitted when a client terminates unexpectedly.
|
||||
## Emitted when a the user stops (terminates) the current test session
|
||||
@warning_ignore("unused_signal")
|
||||
signal gdunit_client_terminated()
|
||||
signal gdunit_test_session_terminate()
|
||||
|
||||
|
||||
## Emitted when a test execution event occurs.[br]
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://kj16fg0hf6kn
|
||||
uid://7fkqtqq0ib25
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://4sujouo3vf6d
|
||||
uid://djyr7is32ffbs
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://ierjyaem56m3
|
||||
uid://cg0fqsmpf8fdh
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dthfh16tl5wqc
|
||||
uid://cqe6i2xbwgneb
|
||||
|
||||
@@ -70,8 +70,14 @@ func scan_directory(resource_path: String) -> Array[Script]:
|
||||
|
||||
|
||||
func _scan_test_suites_scripts(dir: DirAccess, collected_suites: Array[Script]) -> Array[Script]:
|
||||
# Skip excluded directories
|
||||
if dir.file_exists(".gdignore"):
|
||||
prints("Exclude directory %s, containing .gdignore file" % dir.get_current_dir())
|
||||
return []
|
||||
|
||||
if exclude_scan_directories.has(dir.get_current_dir()):
|
||||
return collected_suites
|
||||
|
||||
var err := dir.list_dir_begin()
|
||||
if err != OK:
|
||||
push_error("Error on scanning directory %s" % dir.get_current_dir(), error_string(err))
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://bju0nt1bgsc2s
|
||||
uid://bymtxj63ek2kd
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://d05qgv6uu477i
|
||||
uid://4tbcywx0qg1d
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dehxycxsj68ev
|
||||
uid://d0d4s6tkgoh3b
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://dmta1h7ndfnko
|
||||
uid://dd7g37aslbmm1
|
||||
|
||||
@@ -9,7 +9,8 @@ var _attribute: TestCaseAttribute
|
||||
var _current_iteration: int = -1
|
||||
var _expect_to_interupt := false
|
||||
var _timer: Timer
|
||||
var _interupted: bool = false
|
||||
var _interupted := false
|
||||
var _terminated := false
|
||||
var _failed := false
|
||||
var _parameter_set_resolver: GdUnitTestParameterSetResolver
|
||||
var _is_disposed := false
|
||||
@@ -123,7 +124,7 @@ func do_interrupt() -> void:
|
||||
# We need to dispose manually the function state here
|
||||
GdObjects.dispose_function_state(_func_state)
|
||||
if not is_expect_interupted():
|
||||
var execution_context:= GdUnitThreadManager.get_current_context().get_execution_context()
|
||||
var execution_context := GdUnitThreadManager.get_current_context().get_execution_context()
|
||||
if is_fuzzed():
|
||||
execution_context.add_report(GdUnitReport.new()\
|
||||
.create(GdUnitReport.INTERUPTED, line_number(), GdAssertMessages.fuzzer_interuped(_current_iteration, "timedout")))
|
||||
@@ -133,6 +134,16 @@ func do_interrupt() -> void:
|
||||
completed.emit()
|
||||
|
||||
|
||||
func do_terminate() -> void:
|
||||
_terminated = true
|
||||
# We need to dispose manually the function state here
|
||||
GdObjects.dispose_function_state(_func_state)
|
||||
var execution_context := GdUnitThreadManager.get_current_context().get_execution_context()
|
||||
execution_context.add_report(GdUnitReport.new()\
|
||||
.create(GdUnitReport.TERMINATED, line_number(), GdAssertMessages.test_session_terminated()))
|
||||
completed.emit()
|
||||
|
||||
|
||||
func _set_failure_handler() -> void:
|
||||
if not GdUnitSignals.instance().gdunit_set_test_failed.is_connected(_failure_received):
|
||||
@warning_ignore("return_value_discarded")
|
||||
@@ -172,6 +183,10 @@ func is_expect_interupted() -> bool:
|
||||
return _expect_to_interupt
|
||||
|
||||
|
||||
func is_terminated() -> bool:
|
||||
return _terminated
|
||||
|
||||
|
||||
func is_parameterized() -> bool:
|
||||
return _parameter_set_resolver.is_parameterized()
|
||||
|
||||
@@ -192,11 +207,6 @@ func test_name() -> String:
|
||||
return _test_case.test_name
|
||||
|
||||
|
||||
@warning_ignore("native_method_override")
|
||||
func get_name() -> StringName:
|
||||
return _test_case.test_name
|
||||
|
||||
|
||||
func line_number() -> int:
|
||||
return _test_case.line_number
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://cb2lkpvh0liiv
|
||||
uid://dvhr6i0bdk05n
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://csgvrbao53xmv"
|
||||
uid="uid://c0lvcprd6501t"
|
||||
path="res://.godot/imported/touch-button.png-2fff40c8520d8e97a57db1b2b043f641.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
|
||||
@@ -1 +1 @@
|
||||
uid://d2bres53mgxnw
|
||||
uid://b3ilfkx1js423
|
||||
|
||||
64
addons/gdUnit4/src/core/command/GdUnitBaseCommand.gd
Normal file
64
addons/gdUnit4/src/core/command/GdUnitBaseCommand.gd
Normal file
@@ -0,0 +1,64 @@
|
||||
@abstract class_name GdUnitBaseCommand
|
||||
extends Node
|
||||
|
||||
|
||||
var id: String
|
||||
var icon: Texture2D
|
||||
var shortcut: Shortcut = null
|
||||
var shortcut_type: GdUnitShortcut.ShortCut
|
||||
|
||||
|
||||
func _init(p_id: String, p_shortcut: GdUnitShortcut.ShortCut = GdUnitShortcut.ShortCut.NONE) -> void:
|
||||
id = p_id
|
||||
shortcut_type = p_shortcut
|
||||
_set_shortcut()
|
||||
|
||||
|
||||
func _shortcut_input(event: InputEvent) -> void:
|
||||
if is_running():
|
||||
return
|
||||
|
||||
if shortcut and shortcut.matches_event(event):
|
||||
execute()
|
||||
get_viewport().set_input_as_handled()
|
||||
|
||||
|
||||
func update_shortcut() -> void:
|
||||
_set_shortcut()
|
||||
|
||||
|
||||
func _set_shortcut() -> void:
|
||||
if shortcut_type == GdUnitShortcut.ShortCut.NONE:
|
||||
return
|
||||
|
||||
var property_name := GdUnitShortcut.as_property(shortcut_type)
|
||||
var property := GdUnitSettings.get_property(property_name)
|
||||
var keys := GdUnitShortcut.default_keys(shortcut_type)
|
||||
if property != null:
|
||||
keys = property.value()
|
||||
var inputEvent := _create_shortcut_input_even(keys)
|
||||
|
||||
shortcut = Shortcut.new()
|
||||
shortcut.set_events([inputEvent])
|
||||
|
||||
|
||||
func _create_shortcut_input_even(key_codes: PackedInt32Array) -> InputEventKey:
|
||||
var inputEvent := InputEventKey.new()
|
||||
inputEvent.pressed = true
|
||||
for key_code in key_codes:
|
||||
match key_code:
|
||||
KEY_ALT:
|
||||
inputEvent.alt_pressed = true
|
||||
KEY_SHIFT:
|
||||
inputEvent.shift_pressed = true
|
||||
KEY_CTRL:
|
||||
inputEvent.ctrl_pressed = true
|
||||
_:
|
||||
inputEvent.keycode = key_code as Key
|
||||
inputEvent.physical_keycode = key_code as Key
|
||||
return inputEvent
|
||||
|
||||
|
||||
@abstract func is_running() -> bool
|
||||
|
||||
@abstract func execute(...parameters: Array) -> void
|
||||
1
addons/gdUnit4/src/core/command/GdUnitBaseCommand.gd.uid
Normal file
1
addons/gdUnit4/src/core/command/GdUnitBaseCommand.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bxuturao0ahb5
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user