diff --git a/AttributesExtension.uplugin b/AttributesExtension.uplugin index a35909d..aab4783 100644 --- a/AttributesExtension.uplugin +++ b/AttributesExtension.uplugin @@ -43,6 +43,17 @@ "XboxOne", "Switch" ] + }, + { + "Name" : "AttributesTest", + "Type" : "Developer", + "LoadingPhase" : "PreDefault", + "WhitelistPlatforms": [ + "Win64", + "Win32", + "Linux", + "Mac" + ] } ] } \ No newline at end of file diff --git a/Source/Test/AttributesTest.Build.cs b/Source/Test/AttributesTest.Build.cs new file mode 100644 index 0000000..9c137e1 --- /dev/null +++ b/Source/Test/AttributesTest.Build.cs @@ -0,0 +1,27 @@ +// Copyright 2015-2019 Piperift. All Rights Reserved. + +using UnrealBuildTool; +using System.IO; + +namespace UnrealBuildTool.Rules +{ + public class AttributesTest : ModuleRules { + public AttributesTest(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; + bEnforceIWYU = true; + + PublicDependencyModuleNames.AddRange(new string[] + { + "Core", + "Engine", + "CoreUObject", + "Attributes" + }); + + PrivateDependencyModuleNames.AddRange(new string[] + { + }); + } + } +} \ No newline at end of file diff --git a/Source/Test/Private/Attributes.spec.cpp b/Source/Test/Private/Attributes.spec.cpp new file mode 100644 index 0000000..1ce4748 --- /dev/null +++ b/Source/Test/Private/Attributes.spec.cpp @@ -0,0 +1,54 @@ +// Copyright 2015-2019 Piperift. All Rights Reserved. + +#include "TestHelpers.h" +#include "FloatAttr.h" +#include "Int32Attr.h" + +namespace +{ + constexpr uint32 Flags_Product = EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::ProductFilter; + constexpr uint32 Flags_Smoke = EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::ProductFilter; +} + +#define BASE_SPEC FAESpec + +TESTSPEC(FFloatAttributesSpec, "AttributesExtension.Float", Flags_Smoke) +void FFloatAttributesSpec::Define() +{ + It("Attributes can be instantiated empty", [this]() + { + FFloatAttr Attr; + TestTrue(TEXT("Base Value is set"), Attr.GetBaseValue() == 0.0f); + TestTrue(TEXT("Value is set"), Attr == 0.0f); + }); + + It("Attributes can be instantiated with a base value", [this]() + { + FFloatAttr Attr { 5.f }; + TestTrue(TEXT("Base Value is set"), Attr.GetBaseValue() == 5.0f); + TestTrue(TEXT("Base Value is set"), Attr == 5.0f); + }); +} + +TESTSPEC(FInt32AttributesSpec, "AttributesExtension.Int32", Flags_Smoke) +void FInt32AttributesSpec::Define() +{ + It("Attributes can be instantiated empty", [this]() + { + FInt32Attr Attr; + TestTrue(TEXT("Base Value is set"), Attr.GetBaseValue() == 0); + TestTrue(TEXT("Value is set"), Attr == 0); + }); + + It("Attributes can be instantiated with a base value", [this]() + { + FInt32Attr Attr{ 5 }; + TestTrue(TEXT("Base Value is set"), Attr.GetBaseValue() == 5); + TestTrue(TEXT("Base Value is set"), Attr == 5); + }); +} + +TESTSPEC(FModifiersSpec, "AttributesExtension.Modifiers", Flags_Product) +void FModifiersSpec::Define() +{ +} diff --git a/Source/Test/Private/AttributesTest.cpp b/Source/Test/Private/AttributesTest.cpp new file mode 100644 index 0000000..a8666de --- /dev/null +++ b/Source/Test/Private/AttributesTest.cpp @@ -0,0 +1,3 @@ +// Copyright 2015-2019 Piperift. All Rights Reserved. + +#include "AttributesTest.h" diff --git a/Source/Test/Private/TestHelpers.cpp b/Source/Test/Private/TestHelpers.cpp new file mode 100644 index 0000000..b0196f8 --- /dev/null +++ b/Source/Test/Private/TestHelpers.cpp @@ -0,0 +1,41 @@ +// Copyright 2015-2019 Piperift. All Rights Reserved. + +#include "TestHelpers.h" + +#include +#include +#include +#include +#include +#include + + +UWorld* FAESpec::GetTestWorld() const +{ +#if WITH_EDITOR + const TIndirectArray& WorldContexts = GEngine->GetWorldContexts(); + for (const FWorldContext& Context : WorldContexts) + { + if (Context.World() != nullptr) + { + if (Context.WorldType == EWorldType::PIE /*&& Context.PIEInstance == 0*/) + { + return Context.World(); + } + + if (Context.WorldType == EWorldType::Game) + { + return Context.World(); + } + } + } +#endif + + UWorld* TestWorld = GWorld; + if (GIsEditor) + { + UE_LOG(LogTemp, Warning, TEXT("AttributesExtension Test using GWorld. Not correct for PIE")); + } + + return TestWorld; +} diff --git a/Source/Test/Public/AttributesTest.h b/Source/Test/Public/AttributesTest.h new file mode 100644 index 0000000..1105e8f --- /dev/null +++ b/Source/Test/Public/AttributesTest.h @@ -0,0 +1,24 @@ +// Copyright 2015-2019 Piperift. All Rights Reserved. + +#pragma once + +#include + + +class FAttributesTest : public IModuleInterface +{ +public: + + virtual void StartupModule() override {} + virtual void ShutdownModule() override {} + + static inline FAttributesTest& Get() { + return FModuleManager::LoadModuleChecked("AttributesTest"); + } + + static inline bool IsAvailable() { + return FModuleManager::Get().IsModuleLoaded("AttributesTest"); + } +}; + +IMPLEMENT_MODULE(FAttributesTest, AttributesTest); diff --git a/Source/Test/Public/TestHelpers.h b/Source/Test/Public/TestHelpers.h new file mode 100644 index 0000000..bb5cf75 --- /dev/null +++ b/Source/Test/Public/TestHelpers.h @@ -0,0 +1,76 @@ +// Copyright 2015-2019 Piperift. All Rights Reserved. + +#pragma once + +#include +#include +#include + + +class FAESpec : public FAutomationSpecBase +{ +public: + + FAESpec(const FString& InName, const bool bInComplexTask) + : FAutomationSpecBase(InName, bInComplexTask) + {} + +protected: + + void TestNotImplemented() + { + AddWarning("Test not implemented."); + } + + UWorld* GetTestWorld() const; +}; + + +#define BASE_SPEC FAESpec + +#define BEGIN_TESTSPEC_PRIVATE( TClass, PrettyName, TFlags, FileName, LineNumber ) \ + class TClass : public BASE_SPEC \ + { \ + using Super = BASE_SPEC; \ + public: \ + TClass( const FString& InName ) \ + : Super( InName, false ) { \ + static_assert((TFlags)&EAutomationTestFlags::ApplicationContextMask, "AutomationTest has no application flag. It shouldn't run. See AutomationTest.h."); \ + static_assert( (((TFlags)&EAutomationTestFlags::FilterMask) == EAutomationTestFlags::SmokeFilter) || \ + (((TFlags)&EAutomationTestFlags::FilterMask) == EAutomationTestFlags::EngineFilter) || \ + (((TFlags)&EAutomationTestFlags::FilterMask) == EAutomationTestFlags::ProductFilter) || \ + (((TFlags)&EAutomationTestFlags::FilterMask) == EAutomationTestFlags::PerfFilter) || \ + (((TFlags)&EAutomationTestFlags::FilterMask) == EAutomationTestFlags::StressFilter) || \ + (((TFlags)&EAutomationTestFlags::FilterMask) == EAutomationTestFlags::NegativeFilter), \ + "All AutomationTests must have exactly 1 filter type specified. See AutomationTest.h."); \ + } \ + virtual uint32 GetTestFlags() const override { return TFlags; } \ + using Super::GetTestSourceFileName; \ + virtual FString GetTestSourceFileName() const override { return FileName; } \ + using Super::GetTestSourceFileLine; \ + virtual int32 GetTestSourceFileLine() const override { return LineNumber; } \ + protected: \ + virtual FString GetBeautifiedTestName() const override { return PrettyName; } \ + virtual void Define() override; + + +#if WITH_AUTOMATION_WORKER + #define TESTSPEC( TClass, PrettyName, TFlags ) \ + BEGIN_TESTSPEC_PRIVATE(TClass, PrettyName, TFlags, __FILE__, __LINE__) \ + };\ + namespace\ + {\ + TClass TClass##AutomationSpecInstance( TEXT(#TClass) );\ + } + + #define BEGIN_TESTSPEC( TClass, PrettyName, TFlags ) \ + BEGIN_TESTSPEC_PRIVATE(TClass, PrettyName, TFlags, __FILE__, __LINE__) + + #define END_TESTSPEC( TClass ) \ + };\ + namespace\ + {\ + TClass TClass##AutomationSpecInstance( TEXT(#TClass) );\ + } +#endif +