Unreal Snake Game 1.0.0
TestUtils.h
1// Snake Game, Copyright LifeEXE. All Rights Reserved.
2
3#pragma once
4
5#if WITH_AUTOMATION_TESTS
6
7#include "CoreMinimal.h"
8#include "Engine/Blueprint.h"
9#include "Tests/AutomationCommon.h"
10#include "Blueprint/WidgetBlueprintLibrary.h"
11#include "Blueprint/WidgetTree.h"
12#include "Blueprint/UserWidget.h"
13
14namespace LifeExe
15{
16namespace Test
17{
18template <typename Type1, typename Type2>
19struct TestPayload
20{
21 Type1 TestValue;
22 Type2 ExpectedValue;
23 float Tolerance = KINDA_SMALL_NUMBER;
24};
25
26#define ENUM_LOOP_START(TYPE, EnumElem) \
27 for (int32 Index = 0; Index < StaticEnum<TYPE>()->NumEnums() - 1; ++Index) \
28 { \
29 const auto EnumElem = static_cast<TYPE>(StaticEnum<TYPE>()->GetValueByIndex(Index));
30#define ENUM_LOOP_END }
31
32template <typename EnumType, typename FunctionType>
33void ForEach(FunctionType&& Function)
34{
35 const UEnum* Enum = StaticEnum<EnumType>();
36 for (int32 i = 0; i < Enum->NumEnums(); ++i)
37 {
38 Function(static_cast<EnumType>(Enum->GetValueByIndex(i)));
39 }
40}
41
42template <typename T>
43T* CreateBlueprint(UWorld* World, const FString& Name, const FTransform& Transform = FTransform::Identity)
44{
45 const UBlueprint* Blueprint = LoadObject<UBlueprint>(nullptr, *Name);
46 return (World && Blueprint) ? World->SpawnActor<T>(Blueprint->GeneratedClass, Transform) : nullptr;
47}
48
49template <typename T>
50T* CreateBlueprintDeferred(UWorld* World, const FString& Name, const FTransform& Transform = FTransform::Identity)
51{
52 const UBlueprint* Blueprint = LoadObject<UBlueprint>(nullptr, *Name);
53 return (World && Blueprint) ? World->SpawnActorDeferred<T>(Blueprint->GeneratedClass, Transform) : nullptr;
54}
55
56class LevelScope
57{
58public:
59 LevelScope(const FString& MapName) { AutomationOpenMap(MapName); }
60 ~LevelScope() { ADD_LATENT_AUTOMATION_COMMAND(FExitGameCommand); }
61};
62
63UWorld* GetTestGameWorld();
64
65void CallFuncByNameWithParams(UObject* Object, const FString& FuncName, const TArray<FString>& Params);
66
67class FTPSUntilLatentCommand : public IAutomationLatentCommand
68{
69public:
70 FTPSUntilLatentCommand(TFunction<void()> InCallback, TFunction<void()> InTimeoutCallback, float InTimeout = 5.0f);
71 virtual bool Update() override;
72
73private:
74 TFunction<void()> Callback;
75 TFunction<void()> TimeoutCallback;
76 float Timeout;
77};
78
79int32 GetActionBindingIndexByName(UInputComponent* InputComp, const FString& ActionName, EInputEvent InputEvent);
80int32 GetAxisBindingIndexByName(UInputComponent* InputComp, const FString& AxisName);
81
82FString GetTestDataDir();
83
84template <class T>
85T* FindWidgetByClass()
86{
87 TArray<UUserWidget*> Widgets;
88 UWidgetBlueprintLibrary::GetAllWidgetsOfClass(GetTestGameWorld(), Widgets, T::StaticClass(), false);
89 return Widgets.Num() != 0 ? Cast<T>(Widgets[0]) : nullptr;
90}
91
92UWidget* FindWidgetByName(const UUserWidget* Widget, const FName& WidgetName);
93
94void DoInputAction(UInputComponent* InputComponent, const FString& ActionName, const FKey& Key);
95void JumpPressed(UInputComponent* InputComponent);
96void PausePressed(UInputComponent* InputComponent);
97
98class FTakeScreenshotLatentCommand : public IAutomationLatentCommand
99{
100public:
101 FTakeScreenshotLatentCommand(const FString& InScreenshotName);
102 virtual ~FTakeScreenshotLatentCommand();
103
104protected:
105 const FString ScreenshotName;
106 bool ScreenshotRequested{false};
107 bool CommandCompleted{false};
108
109 virtual void OnScreenshotTakenAndCompared();
110};
111
112class FTakeGameScreenshotLatentCommand : public FTakeScreenshotLatentCommand
113{
114public:
115 FTakeGameScreenshotLatentCommand(const FString& InScreenshotName);
116
117 virtual bool Update() override;
118};
119
120class FTakeUIScreenshotLatentCommand : public FTakeScreenshotLatentCommand
121{
122public:
123 FTakeUIScreenshotLatentCommand(const FString& InScreenshotName);
124 virtual bool Update() override;
125
126private:
127 bool ScreenshotSetupDone{false};
128
129 virtual void OnScreenshotTakenAndCompared() override;
130 void SetBufferVisualization(const FName& VisualizeBuffer);
131};
132
133void SpecCloseLevel(UWorld* World);
134
135template <class ObjectClass, class PropertyClass>
136PropertyClass GetPropertyValueByName(ObjectClass* Obj, const FString& PropName)
137{
138 if (!Obj) return PropertyClass();
139 for (TFieldIterator<FProperty> PropIt(Obj->StaticClass()); PropIt; ++PropIt)
140 {
141 const FProperty* Property = *PropIt;
142 if (Property && Property->GetName().Equals(PropName))
143 {
144 return *Property->ContainerPtrToValuePtr<PropertyClass>(Obj);
145 }
146 }
147 return PropertyClass();
148}
149
150} // namespace Test
151} // namespace LifeExe
152
153#endif