SmartPointer<ParameterizedCommand> RegistryPersistence::ReadParameters( const SmartPointer<IConfigurationElement>& configurationElement, QList<SmartPointer<IStatus> >& warningsToLog, const SmartPointer<Command>& command) { const QList<IConfigurationElement::Pointer> parameterElements = configurationElement ->GetChildren(TAG_PARAMETER); if (parameterElements.isEmpty()) { ParameterizedCommand::Pointer result(new ParameterizedCommand(command, QList<Parameterization>())); return result; } QList<Parameterization> parameters; foreach (const IConfigurationElement::Pointer& parameterElement, parameterElements) { // Read out the id. const QString id = parameterElement->GetAttribute(ATT_ID); if (id.isEmpty()) { // The id should never be null. This is invalid. AddWarning(warningsToLog, "Parameters need an id", configurationElement); continue; } // Find the parameter on the command. IParameter::Pointer parameter; try { const QList<IParameter::Pointer> commandParameters = command->GetParameters(); foreach (const IParameter::Pointer& currentParameter, commandParameters) { if (currentParameter->GetId() == id) { parameter = currentParameter; break; } } } catch (const NotDefinedException& /*e*/) { // This should not happen. } if (parameter.IsNull()) { // The name should never be null. This is invalid. AddWarning(warningsToLog, "Could not find a matching parameter", configurationElement, id); continue; } // Read out the value. const QString value = parameterElement->GetAttribute(ATT_VALUE); if (value.isEmpty()) { // The name should never be null. This is invalid. AddWarning(warningsToLog, "Parameters need a value", configurationElement, id); continue; } parameters.push_back(Parameterization(parameter, value)); } if (parameters.isEmpty()) { ParameterizedCommand::Pointer result(new ParameterizedCommand(command, QList<Parameterization>())); return result; } ParameterizedCommand::Pointer result(new ParameterizedCommand(command, parameters)); return result; }
bool UFunctionalTestingManager::RunFirstValidTest() { bool bTestSuccessfullyTriggered = false; if (TestReproStrings.Num() > 0) { UWorld* World = GetWorld(); UObject* TestsOuter = World ? (UObject*)(World->PersistentLevel) : (UObject*)(ANY_PACKAGE); while (TestReproStrings.Num() > 0) { TArray<FString> TestParams; const FString SingleTestReproString = TestReproStrings.Pop(/*bAllowShrinking=*/false); SingleTestReproString.ParseIntoArray(&TestParams, TEXT("#"), /*InCullEmpty=*/true); if (TestParams.Num() == 0) { AddWarning(FText::FromString(FString::Printf(TEXT("Unable to parse \'%s\'"), *SingleTestReproString))); continue; } // first param is the test name. Look for it const FString TestName = TestParams[0]; TestParams.RemoveAt(0, 1, /*bAllowShrinking=*/false); AFunctionalTest* TestToRun = FindObject<AFunctionalTest>(TestsOuter, *TestName); if (TestToRun) { TestToRun->TestFinishedObserver = TestFinishedObserver; if (TestToRun->StartTest(TestParams)) { bTestSuccessfullyTriggered = true; break; } else { AddWarning(FText::FromString(FString::Printf(TEXT("Test \'%s\' failed to start"), *TestToRun->GetName()))); } } else { AddWarning(FText::FromString(FString::Printf(TEXT("Unable to find test \'%s\'"), *TestName))); } } } if (bTestSuccessfullyTriggered == false) { for (int32 Index = TestsLeft.Num()-1; Index >= 0; --Index) { bool bRemove = TestsLeft[Index] == NULL; if (TestsLeft[Index] != NULL) { ensure(TestsLeft[Index]->bIsEnabled); TestsLeft[Index]->TestFinishedObserver = TestFinishedObserver; if (TestsLeft[Index]->StartTest()) { bTestSuccessfullyTriggered = true; break; } else { AddWarning(FText::FromString(FString::Printf(TEXT("Test: %s failed to start"), *TestsLeft[Index]->GetName()))); bRemove = true; } } if (bRemove) { TestsLeft.RemoveAtSwap(Index, 1, false); } } } return bTestSuccessfullyTriggered; }
/** * Runs compile-on-load test against all unloaded, and optionally loaded, blueprints * See the TestAllBlueprints config key in the [Automation.Blueprint] config sections */ bool FBlueprintCompileOnLoadTest::RunTest(const FString& BlueprintAssetPath) { FCompilerResultsLog Results; UBlueprint* ExistingBP = nullptr; // if this blueprint was already loaded, then these tests are invalidated // (because dependencies have already been loaded) if (FBlueprintAutomationTestUtilities::IsBlueprintLoaded(BlueprintAssetPath, &ExistingBP)) { if (FBlueprintAutomationTestUtilities::IsAssetUnsaved(BlueprintAssetPath)) { AddError(FString::Printf(TEXT("You have unsaved changes made to '%s', please save them before running this test."), *BlueprintAssetPath)); return false; } else { AddWarning(FString::Printf(TEXT("Test may be invalid (the blueprint is already loaded): '%s'"), *BlueprintAssetPath)); FBlueprintAutomationTestUtilities::UnloadBlueprint(ExistingBP); } } // tracks blueprints that were already loaded (and cleans up any that were // loaded in its lifetime, once it is destroyed) FScopedBlueprintUnloader NewBlueprintUnloader(/*bAutoOpenScope =*/true, /*bRunGCOnCloseIn =*/true); // We load the blueprint twice and compare the two for discrepancies. This is // to bring dependency load issues to light (among other things). If a blueprint's // dependencies are loaded too late, then this first object is the degenerate one. UBlueprint* InitialBlueprint = Cast<UBlueprint>(StaticLoadObject(UBlueprint::StaticClass(), NULL, *BlueprintAssetPath)); // if we failed to load it the first time, then there is no need to make a // second attempt, leave them to fix up this issue first if (InitialBlueprint == NULL) { AddError(*FString::Printf(TEXT("Unable to load blueprint for: '%s'"), *BlueprintAssetPath)); return false; } if (!InitialBlueprint->SkeletonGeneratedClass || !InitialBlueprint->GeneratedClass) { AddError(*FString::Printf(TEXT("Unable to load blueprint for: '%s'. Probably it derives from an invalid class."), *BlueprintAssetPath)); return false; } // GATHER SUBOBJECTS TArray<TWeakObjectPtr<UObject>> InitialBlueprintSubobjects; { TArray<UObject*> InitialBlueprintSubobjectsPtr; GetObjectsWithOuter(InitialBlueprint, InitialBlueprintSubobjectsPtr); for (auto Obj : InitialBlueprintSubobjectsPtr) { InitialBlueprintSubobjects.Add(Obj); } } // GATHER DEPENDENCIES TSet<TWeakObjectPtr<UBlueprint>> BlueprintDependencies; { TArray<UBlueprint*> DependentBlueprints; FBlueprintEditorUtils::GetDependentBlueprints(InitialBlueprint, DependentBlueprints); for (auto BP : DependentBlueprints) { BlueprintDependencies.Add(BP); } } BlueprintDependencies.Add(InitialBlueprint); // GATHER DEPENDENCIES PERSISTENT DATA struct FReplaceInnerData { TWeakObjectPtr<UClass> Class; FStringAssetReference BlueprintAsset; }; TArray<FReplaceInnerData> ReplaceInnerData; for (auto BPToUnloadWP : BlueprintDependencies) { auto BPToUnload = BPToUnloadWP.Get(); auto OldClass = BPToUnload ? *BPToUnload->GeneratedClass : NULL; if (OldClass) { FReplaceInnerData Data; Data.Class = OldClass; Data.BlueprintAsset = FStringAssetReference(BPToUnload); ReplaceInnerData.Add(Data); } } // store off data for the initial blueprint so we can unload it (and reconstruct // later to compare it with a second one) TArray<uint8> InitialLoadData; FObjectWriter(InitialBlueprint, InitialLoadData); // grab the name before we unload the blueprint FName const BlueprintName = InitialBlueprint->GetFName(); // unload the blueprint so we can reload it (to catch any differences, now // that all its dependencies should be loaded as well) //UNLOAD DEPENDENCIES, all circular dependencies will be loaded again // unload the blueprint so we can reload it (to catch any differences, now // that all its dependencies should be loaded as well) for (auto BPToUnloadWP : BlueprintDependencies) { if (auto BPToUnload = BPToUnloadWP.Get()) { FBlueprintAutomationTestUtilities::UnloadBlueprint(BPToUnload); } } // this blueprint is now dead (will be destroyed next garbage-collection pass) UBlueprint* UnloadedBlueprint = InitialBlueprint; InitialBlueprint = NULL; // load the blueprint a second time; if the two separately loaded blueprints // are different, then this one is most likely the choice one (it has all its // dependencies loaded) UBlueprint* ReloadedBlueprint = Cast<UBlueprint>(StaticLoadObject(UBlueprint::StaticClass(), NULL, *BlueprintAssetPath)); UPackage* TransientPackage = GetTransientPackage(); FName ReconstructedName = MakeUniqueObjectName(TransientPackage, UBlueprint::StaticClass(), BlueprintName); // reconstruct the initial blueprint (using the serialized data from its initial load) EObjectFlags const StandardBlueprintFlags = RF_Public | RF_Standalone | RF_Transactional; InitialBlueprint = ConstructObject<UBlueprint>(UBlueprint::StaticClass(), TransientPackage, ReconstructedName, StandardBlueprintFlags | RF_Transient); FObjectReader(InitialBlueprint, InitialLoadData); { TMap<UObject*, UObject*> ClassRedirects; for (auto& Data : ReplaceInnerData) { UClass* OriginalClass = Data.Class.Get(); UBlueprint* NewBlueprint = Cast<UBlueprint>(Data.BlueprintAsset.ResolveObject()); UClass* NewClass = NewBlueprint ? *NewBlueprint->GeneratedClass : NULL; if (OriginalClass && NewClass) { ClassRedirects.Add(OriginalClass, NewClass); } } // REPLACE OLD DATA FArchiveReplaceObjectRef<UObject>(InitialBlueprint, ClassRedirects, /*bNullPrivateRefs=*/false, /*bIgnoreOuterRef=*/true, /*bIgnoreArchetypeRef=*/false); for (auto SubobjWP : InitialBlueprintSubobjects) { if (auto Subobj = SubobjWP.Get()) { FArchiveReplaceObjectRef<UObject>(Subobj, ClassRedirects, /*bNullPrivateRefs=*/false, /*bIgnoreOuterRef=*/true, /*bIgnoreArchetypeRef=*/false); } } UPackage* AssetPackage = ReloadedBlueprint->GetOutermost(); bool bHasUnsavedChanges = AssetPackage->IsDirty(); FBlueprintEditorUtils::RefreshAllNodes(ReloadedBlueprint); AssetPackage->SetDirtyFlag(bHasUnsavedChanges); } // look for diffs between subsequent loads and log them as errors TArray<FDiffSingleResult> BlueprintDiffs; bool bDiffsFound = FBlueprintAutomationTestUtilities::DiffBlueprints(InitialBlueprint, ReloadedBlueprint, BlueprintDiffs); if (bDiffsFound) { FBlueprintAutomationTestUtilities::ResolveCircularDependencyDiffs(ReloadedBlueprint, BlueprintDiffs); // if there are still diffs after resolving any the could have been from unloaded circular dependencies if (BlueprintDiffs.Num() > 0) { AddError(FString::Printf(TEXT("Inconsistencies between subsequent blueprint loads for: '%s' (was a dependency not preloaded?)"), *BlueprintAssetPath)); } else { bDiffsFound = false; } // list all the differences (so as to help identify what dependency was missing) for (auto DiffIt(BlueprintDiffs.CreateIterator()); DiffIt; ++DiffIt) { // will be presented in the context of "what changed between the initial load and the second?" FString DiffDescription = DiffIt->ToolTip; if (DiffDescription != DiffIt->DisplayString) { DiffDescription = FString::Printf(TEXT("%s (%s)"), *DiffDescription, *DiffIt->DisplayString); } const UEdGraphNode* NodeFromPin = DiffIt->Pin1 ? Cast<const UEdGraphNode>(DiffIt->Pin1->GetOuter()) : NULL; const UEdGraphNode* Node = DiffIt->Node1 ? DiffIt->Node1 : NodeFromPin; const UEdGraph* Graph = Node ? Node->GetGraph() : NULL; const FString GraphName = Graph ? Graph->GetName() : FString(TEXT("Unknown Graph")); AddError(FString::Printf(TEXT("%s.%s differs between subsequent loads: %s"), *BlueprintName.ToString(), *GraphName, *DiffDescription)); } } // At the close of this function, the FScopedBlueprintUnloader should prep // for following tests by unloading any blueprint dependencies that were // loaded for this one (should catch InitialBlueprint and ReloadedBlueprint) // // The FScopedBlueprintUnloader should also run garbage-collection after, // in hopes that the imports for this blueprint get destroyed so that they // don't invalidate other tests that share the same dependencies return !bDiffsFound; }
bool FDateTimeFormattingRulesTest::RunTest (const FString& Parameters) { #if UE_ENABLE_ICU FInternationalization& I18N = FInternationalization::Get(); const FString OriginalCulture = I18N.GetCurrentCulture()->GetName(); const FDateTime UnixEpoch = FDateTime::FromUnixTimestamp(0); const FDateTime UnixBillennium = FDateTime::FromUnixTimestamp(1000000000); const FDateTime UnixOnes = FDateTime::FromUnixTimestamp(1111111111); const FDateTime UnixDecimalSequence = FDateTime::FromUnixTimestamp(1234567890); const FDateTime TestDateTime( 1990, 6, 13, 12, 34, 56, 789 ); if (I18N.SetCurrentCulture("en-US")) { // Unix Time Values via Date Time Test( this, TEXT("Testing Unix Epoch"), FText::AsDateTime(UnixEpoch, EDateTimeStyle::Short, EDateTimeStyle::Short, "GMT"), FText::FromString( TEXT("1/1/70, 12:00 AM") ) ); Test( this, TEXT("Testing Unix Epoch"), FText::AsDateTime(UnixEpoch, EDateTimeStyle::Medium, EDateTimeStyle::Medium, "GMT"), FText::FromString( TEXT("Jan 1, 1970, 12:00:00 AM") ) ); Test( this, TEXT("Testing Unix Epoch"), FText::AsDateTime(UnixEpoch, EDateTimeStyle::Long, EDateTimeStyle::Long, "GMT"), FText::FromString( TEXT("January 1, 1970 at 12:00:00 AM GMT") ) ); Test( this, TEXT("Testing Unix Epoch"), FText::AsDateTime(UnixEpoch, EDateTimeStyle::Full, EDateTimeStyle::Full, "GMT"), FText::FromString( TEXT("Thursday, January 1, 1970 at 12:00:00 AM GMT") ) ); Test( this, TEXT("Testing Unix Billennium"), FText::AsDateTime(UnixBillennium, EDateTimeStyle::Short, EDateTimeStyle::Short, "GMT"), FText::FromString( TEXT("9/9/01, 1:46 AM") ) ); Test( this, TEXT("Testing Unix Billennium"), FText::AsDateTime(UnixBillennium, EDateTimeStyle::Medium, EDateTimeStyle::Medium, "GMT"), FText::FromString( TEXT("Sep 9, 2001, 1:46:40 AM") ) ); Test( this, TEXT("Testing Unix Billennium"), FText::AsDateTime(UnixBillennium, EDateTimeStyle::Long, EDateTimeStyle::Long, "GMT"), FText::FromString( TEXT("September 9, 2001 at 1:46:40 AM GMT") ) ); Test( this, TEXT("Testing Unix Billennium"), FText::AsDateTime(UnixBillennium, EDateTimeStyle::Full, EDateTimeStyle::Full, "GMT"), FText::FromString( TEXT("Sunday, September 9, 2001 at 1:46:40 AM GMT") ) ); Test( this, TEXT("Testing Unix Ones"), FText::AsDateTime(UnixOnes, EDateTimeStyle::Short, EDateTimeStyle::Short, "GMT"), FText::FromString( TEXT("3/18/05, 1:58 AM") ) ); Test( this, TEXT("Testing Unix Ones"), FText::AsDateTime(UnixOnes, EDateTimeStyle::Medium, EDateTimeStyle::Medium, "GMT"), FText::FromString( TEXT("Mar 18, 2005, 1:58:31 AM") ) ); Test( this, TEXT("Testing Unix Ones"), FText::AsDateTime(UnixOnes, EDateTimeStyle::Long, EDateTimeStyle::Long, "GMT"), FText::FromString( TEXT("March 18, 2005 at 1:58:31 AM GMT") ) ); Test( this, TEXT("Testing Unix Ones"), FText::AsDateTime(UnixOnes, EDateTimeStyle::Full, EDateTimeStyle::Full, "GMT"), FText::FromString( TEXT("Friday, March 18, 2005 at 1:58:31 AM GMT") ) ); Test( this, TEXT("Testing Unix Decimal Sequence"), FText::AsDateTime(UnixDecimalSequence, EDateTimeStyle::Short, EDateTimeStyle::Short, "GMT"), FText::FromString( TEXT("2/13/09, 11:31 PM") ) ); Test( this, TEXT("Testing Unix Decimal Sequence"), FText::AsDateTime(UnixDecimalSequence, EDateTimeStyle::Medium, EDateTimeStyle::Medium, "GMT"), FText::FromString( TEXT("Feb 13, 2009, 11:31:30 PM") ) ); Test( this, TEXT("Testing Unix Decimal Sequence"), FText::AsDateTime(UnixDecimalSequence, EDateTimeStyle::Long, EDateTimeStyle::Long, "GMT"), FText::FromString( TEXT("February 13, 2009 at 11:31:30 PM GMT") ) ); Test( this, TEXT("Testing Unix Decimal Sequence"), FText::AsDateTime(UnixDecimalSequence, EDateTimeStyle::Full, EDateTimeStyle::Full, "GMT"), FText::FromString( TEXT("Friday, February 13, 2009 at 11:31:30 PM GMT") ) ); // Date Time Test( this, TEXT("Testing Date-Time"), FText::AsDateTime(TestDateTime, EDateTimeStyle::Short,EDateTimeStyle::Short, "GMT"), FText::FromString( TEXT("6/13/90, 12:34 PM") ) ); Test( this, TEXT("Testing Date-Time"), FText::AsDateTime(TestDateTime, EDateTimeStyle::Medium, EDateTimeStyle::Medium, "GMT"), FText::FromString( TEXT("Jun 13, 1990, 12:34:56 PM") ) ); Test( this, TEXT("Testing Date-Time"), FText::AsDateTime(TestDateTime, EDateTimeStyle::Long, EDateTimeStyle::Long, "GMT"), FText::FromString( TEXT("June 13, 1990 at 12:34:56 PM GMT") ) ); Test( this, TEXT("Testing Date-Time"), FText::AsDateTime(TestDateTime, EDateTimeStyle::Full, EDateTimeStyle::Full, "GMT"), FText::FromString( TEXT("Wednesday, June 13, 1990 at 12:34:56 PM GMT") ) ); } else { AddWarning(FString::Printf(TEXT("Internationalization data for %s missing - test is partially disabled."), TEXT("en-US"))); } if (I18N.SetCurrentCulture("ja-JP")) { // Unix Time Values via Date Time Test( this, TEXT("Testing Unix Epoch"), FText::AsDateTime(UnixEpoch, EDateTimeStyle::Short, EDateTimeStyle::Short, "GMT"), FText::FromString( TEXT("1970/01/01 0:00") ) ); Test( this, TEXT("Testing Unix Epoch"), FText::AsDateTime(UnixEpoch, EDateTimeStyle::Medium, EDateTimeStyle::Medium, "GMT"), FText::FromString( TEXT("1970/01/01 0:00:00") ) ); Test( this, TEXT("Testing Unix Epoch"), FText::AsDateTime(UnixEpoch, EDateTimeStyle::Long, EDateTimeStyle::Long, "GMT"), FText::FromString( TEXT("1970\x5E74") TEXT("1\x6708") TEXT("1\x65E5") TEXT(" 0:00:00 GMT") ) ); Test( this, TEXT("Testing Unix Epoch"), FText::AsDateTime(UnixEpoch, EDateTimeStyle::Full, EDateTimeStyle::Full, "GMT"), FText::FromString( TEXT("1970\x5E74") TEXT("1\x6708") TEXT("1\x65E5\x6728\x66DC\x65E5") TEXT(" ") TEXT("0\x6642") TEXT("00\x5206") TEXT("00\x79D2") TEXT(" GMT") ) ); Test( this, TEXT("Testing Unix Billennium"), FText::AsDateTime(UnixBillennium, EDateTimeStyle::Short, EDateTimeStyle::Short, "GMT"), FText::FromString( TEXT("2001/09/09 1:46") ) ); Test( this, TEXT("Testing Unix Billennium"), FText::AsDateTime(UnixBillennium, EDateTimeStyle::Medium, EDateTimeStyle::Medium, "GMT"), FText::FromString( TEXT("2001/09/09 1:46:40") ) ); Test( this, TEXT("Testing Unix Billennium"), FText::AsDateTime(UnixBillennium, EDateTimeStyle::Long, EDateTimeStyle::Long, "GMT"), FText::FromString( TEXT("2001\x5E74") TEXT("9\x6708") TEXT("9\x65E5") TEXT(" 1:46:40 GMT") ) ); Test( this, TEXT("Testing Unix Billennium"), FText::AsDateTime(UnixBillennium, EDateTimeStyle::Full, EDateTimeStyle::Full, "GMT"), FText::FromString( TEXT("2001\x5E74") TEXT("9\x6708") TEXT("9\x65E5\x65E5\x66DC\x65E5") TEXT(" ") TEXT("1\x6642") TEXT("46\x5206") TEXT("40\x79D2") TEXT(" GMT") ) ); Test( this, TEXT("Testing Unix Ones"), FText::AsDateTime(UnixOnes, EDateTimeStyle::Short, EDateTimeStyle::Short, "GMT"), FText::FromString( TEXT("2005/03/18 1:58") ) ); Test( this, TEXT("Testing Unix Ones"), FText::AsDateTime(UnixOnes, EDateTimeStyle::Medium, EDateTimeStyle::Medium, "GMT"), FText::FromString( TEXT("2005/03/18 1:58:31") ) ); Test( this, TEXT("Testing Unix Ones"), FText::AsDateTime(UnixOnes, EDateTimeStyle::Long, EDateTimeStyle::Long, "GMT"), FText::FromString( TEXT("2005\x5E74") TEXT("3\x6708") TEXT("18\x65E5") TEXT(" 1:58:31 GMT") ) ); Test( this, TEXT("Testing Unix Ones"), FText::AsDateTime(UnixOnes, EDateTimeStyle::Full, EDateTimeStyle::Full, "GMT"), FText::FromString( TEXT("2005\x5E74") TEXT("3\x6708") TEXT("18\x65E5\x91D1\x66DC\x65E5") TEXT(" ") TEXT("1\x6642") TEXT("58\x5206") TEXT("31\x79D2") TEXT(" GMT") ) ); Test( this, TEXT("Testing Unix Decimal Sequence"), FText::AsDateTime(UnixDecimalSequence, EDateTimeStyle::Short, EDateTimeStyle::Short, "GMT"), FText::FromString( TEXT("2009/02/13 23:31") ) ); Test( this, TEXT("Testing Unix Decimal Sequence"), FText::AsDateTime(UnixDecimalSequence, EDateTimeStyle::Medium, EDateTimeStyle::Medium, "GMT"), FText::FromString( TEXT("2009/02/13 23:31:30") ) ); Test( this, TEXT("Testing Unix Decimal Sequence"), FText::AsDateTime(UnixDecimalSequence, EDateTimeStyle::Long, EDateTimeStyle::Long, "GMT"), FText::FromString( TEXT("2009\x5E74") TEXT("2\x6708") TEXT("13\x65E5 23:31:30 GMT") ) ); Test( this, TEXT("Testing Unix Decimal Sequence"), FText::AsDateTime(UnixDecimalSequence, EDateTimeStyle::Full, EDateTimeStyle::Full, "GMT"), FText::FromString( TEXT("2009\x5E74") TEXT("2\x6708") TEXT("13\x65E5\x91D1\x66DC\x65E5") TEXT(" ") TEXT("23\x6642") TEXT("31\x5206") TEXT("30\x79D2") TEXT(" GMT") ) ); // Date Time Test( this, TEXT("Testing Date-Time"), FText::AsDateTime(TestDateTime, EDateTimeStyle::Short,EDateTimeStyle::Short, "GMT"), FText::FromString( TEXT("1990/06/13 12:34") ) ); Test( this, TEXT("Testing Date-Time"), FText::AsDateTime(TestDateTime, EDateTimeStyle::Medium, EDateTimeStyle::Medium, "GMT"), FText::FromString( TEXT("1990/06/13 12:34:56") ) ); Test( this, TEXT("Testing Date-Time"), FText::AsDateTime(TestDateTime, EDateTimeStyle::Long, EDateTimeStyle::Long, "GMT"), FText::FromString( TEXT("1990\x5E74") TEXT("6\x6708") TEXT("13\x65E5") TEXT(" 12:34:56 GMT") ) ); Test( this, TEXT("Testing Date-Time"), FText::AsDateTime(TestDateTime, EDateTimeStyle::Full, EDateTimeStyle::Full, "GMT"), FText::FromString( TEXT("1990\x5E74") TEXT("6\x6708") TEXT("13\x65E5\x6C34\x66DC\x65E5") TEXT(" ") TEXT("12\x6642") TEXT("34\x5206") TEXT("56\x79D2 GMT") ) ); } else { AddWarning(FString::Printf(TEXT("Internationalization data for %s missing - test is partially disabled."), TEXT("ja-JP"))); } I18N.SetCurrentCulture(OriginalCulture); #else AddWarning("ICU is disabled thus locale-aware date/time formatting is disabled."); #endif return true; }
bool FBlueprintRenameAndCloneTest::RunTest(const FString& BlueprintAssetPath) { bool bTestFailed = false; if (FBlueprintAutomationTestUtilities::IsAssetUnsaved(BlueprintAssetPath)) { bTestFailed = true; AddError(FString::Printf(TEXT("You have unsaved changes made to '%s', please save them before running this test."), *BlueprintAssetPath)); } bool bIsAlreadyLoaded = false; if (FBlueprintAutomationTestUtilities::IsBlueprintLoaded(BlueprintAssetPath)) { bIsAlreadyLoaded = true; AddWarning(FString::Printf(TEXT("'%s' is already loaded, and possibly referenced by external objects (unable to perform rename tests... please run again in an empty map)."), *BlueprintAssetPath)); } // track the loaded blueprint (and any other BP dependencies) so we can // unload them if we end up renaming it. FScopedBlueprintUnloader NewBlueprintUnloader(/*bAutoOpenScope =*/true, /*bRunGCOnCloseIn =*/false); UBlueprint* const OriginalBlueprint = Cast<UBlueprint>(StaticLoadObject(UBlueprint::StaticClass(), NULL, *BlueprintAssetPath)); if (OriginalBlueprint == NULL) { bTestFailed = true; AddError(FString::Printf(TEXT("Failed to load '%s' (has it been renamed?)."), *BlueprintAssetPath)); } if (!OriginalBlueprint->SkeletonGeneratedClass || !OriginalBlueprint->GeneratedClass) { bTestFailed = true; AddError(*FString::Printf(TEXT("Unable to load blueprint for: '%s'. Probably it derives from an invalid class."), *BlueprintAssetPath)); } else if (!bTestFailed) { // duplicate { UBlueprint* DuplicateBluprint = FBlueprintAutomationTestUtilities::DuplicateBlueprint(OriginalBlueprint); if (!FBlueprintAutomationTestUtilities::TestSaveBlueprint(DuplicateBluprint)) { AddError(FString::Printf(TEXT("Failed to save blueprint after duplication: '%s'"), *BlueprintAssetPath)); bTestFailed = true; } FBlueprintAutomationTestUtilities::UnloadBlueprint(DuplicateBluprint); } // rename if (!bIsAlreadyLoaded) { // store the original package so we can manually invalidate it after the move UPackage* const OriginalPackage = Cast<UPackage>(OriginalBlueprint->GetOutermost()); FString const BlueprintName = OriginalBlueprint->GetName(); UPackage* TempPackage = FBlueprintAutomationTestUtilities::CreateTempPackage(BlueprintName); FString NewName = FString::Printf(TEXT("%s-Rename"), *BlueprintName); NewName = MakeUniqueObjectName(TempPackage, OriginalBlueprint->GetClass(), *NewName).ToString(); OriginalBlueprint->Rename(*NewName, TempPackage, REN_None); if (!FBlueprintAutomationTestUtilities::TestSaveBlueprint(OriginalBlueprint)) { AddError(FString::Printf(TEXT("Failed to save blueprint after rename: '%s'"), *BlueprintAssetPath)); bTestFailed = true; } // the blueprint has been moved out of this package, invalidate it so // we don't save it in this state and so we can reload the blueprint later FBlueprintAutomationTestUtilities::InvalidatePackage(OriginalPackage); // need to unload the renamed blueprint (and any other blueprints // that were relying on it), so that the renamed blueprint doesn't get used by the user FBlueprintAutomationTestUtilities::UnloadBlueprint(OriginalBlueprint); NewBlueprintUnloader.CloseScope(); } else { // no need to unload the blueprint or any of its dependencies (since // we didn't muck with it by renaming it) NewBlueprintUnloader.ClearScope(); } #if WITH_EDITOR // clear undo history to ensure that the transaction buffer isn't // holding onto any references to the blueprints we want unloaded GEditor->Trans->Reset(NSLOCTEXT("BpAutomation", "RenameCloneTest", "Rename and Clone Test")); #endif // #if WITH_EDITOR // make sure the unloaded blueprints are properly flushed (for future tests) CollectGarbage(RF_Native); } return !bTestFailed; }