예제 #1
0
void Test1(TUint32 aInt, TInt aDivisorExp)
	{
	TRealX realx;
	SRatio r0x;
	SRatio r0;
	SRatio r1x;
	SRatio r1;
	TInt r;
	test.Printf(_L("Test1 %08x %d\n"), aInt, aDivisorExp);
	r = RatioSetValue(realx, aInt, aDivisorExp);
	test_KErrNone(r);
	r = RealToRatio(r0x, realx);
	test_KErrNone(r);
	r = Driver.RatioSet(r0, aInt, aDivisorExp);
	RatioPrint2("R0X,R0", r0x, r0);
	TestEqual(r0, r0x);
	Test1M(r0);
	r1x = r0x;
	r = RatioReciprocal(r1x);
	test_KErrNone(r);
	r1 = r0;
	r = Driver.RatioReciprocal(r1);
	test_KErrNone(r);
	RatioPrint2("R1X,R1", r1x, r1);
	TestEqual(r1, r1x);
	Test1M(r1);
	}
bool FCircularBufferTest::RunTest( const FString& Parameters )
{
	// buffer capacity
	TCircularBuffer<int32> b1_1(127);
	TCircularBuffer<int32> b1_2(128);
	TCircularBuffer<int32> b1_3(129);

	TestEqual(TEXT("Buffer capacity of 127 must be rounded up to 128"), b1_1.Capacity(), 128u);
	TestEqual(TEXT("Buffer capacity of 128 must not change"), b1_2.Capacity(), 128u);
	TestEqual(TEXT("Buffer capacity of 129 must be rounded up to 256"), b1_3.Capacity(), 256u);

	// initial values
	TCircularBuffer<int32> b2_1(64, 666);

	for (uint32 Index = 0; Index < b2_1.Capacity(); ++Index)
	{
		TestEqual(FString::Printf(TEXT("Initial value must be correct (%i)"), Index), b2_1[Index], 666);
	}

	// indexing
	TCircularBuffer<int32> b3_1(64, 0);

	TestEqual(TEXT("Next index from 0 must be 1"), b3_1.GetNextIndex(0), 1u);
	TestEqual(TEXT("Next index from 63 must be 0"), b3_1.GetNextIndex(63), 0u);
	TestEqual(TEXT("Next index from 64 must be 1"), b3_1.GetNextIndex(64), 1u);

	b3_1[0] = 42;
	b3_1[65] = 42;

	TestEqual(TEXT("Index 0 must be written and read correctly"), b3_1[0], 42);
	TestEqual(TEXT("Index 1 must be written and read correctly"), b3_1[1], 42);
	TestEqual(TEXT("Index 65 must be written and read correctly"), b3_1[65], 42);

	return true;
}
예제 #3
0
	void Test_ManaBuff()
	{
		const float BuffValue = 30.f;
		const float StartingMana = DestComponent->GetSet<UAbilitySystemTestAttributeSet>()->Mana;

		FActiveGameplayEffectHandle BuffHandle;

		// apply the buff
		{
			CONSTRUCT_CLASS(UGameplayEffect, DamageBuffEffect);
			AddModifier(DamageBuffEffect, GET_FIELD_CHECKED(UAbilitySystemTestAttributeSet, Mana), EGameplayModOp::Additive, FScalableFloat(BuffValue));
			DamageBuffEffect->DurationPolicy = EGameplayEffectDurationType::Infinite;

			BuffHandle = SourceComponent->ApplyGameplayEffectToTarget(DamageBuffEffect, DestComponent, 1.f);
		}

		// check that the value changed
		TestEqual(SKILL_TEST_TEXT("Mana Buffed"), DestComponent->GetSet<UAbilitySystemTestAttributeSet>()->Mana, StartingMana + BuffValue);

		// remove the effect
		{
			DestComponent->RemoveActiveGameplayEffect(BuffHandle);
		}

		// check that the value changed back
		TestEqual(SKILL_TEST_TEXT("Mana Restored"), DestComponent->GetSet<UAbilitySystemTestAttributeSet>()->Mana, StartingMana);
	}
bool FCircularQueueTest::RunTest( const FString& Parameters )
{
	const uint32 QueueSize = 8;

	// empty queue
	{
		TCircularQueue<int32> Queue(QueueSize);

		TestTrue(TEXT("Newly created queues must be empty"), Queue.IsEmpty());
		TestFalse(TEXT("Newly created queues must not be full"), Queue.IsFull());
	}

	// partially filled
	{
		TCircularQueue<int32> Queue(QueueSize);
		int32 Value;
	
		TestTrue(TEXT("Adding to an empty queue must succeed"), Queue.Enqueue(666));
		TestFalse(TEXT("Partially filled queues must not be empty"), Queue.IsEmpty());
		TestFalse(TEXT("Partially filled queues must not be full"), Queue.IsFull());
		TestTrue(TEXT("Peeking at a partially filled queue must succeed"), Queue.Peek(Value));
	}

	// full queue
	{
		TCircularQueue<int32> Queue(QueueSize);

		for (int32 Index = 0; Index < QueueSize - 1; ++Index)
		{
			TestTrue(TEXT("Adding to non-full queue must succeed"), Queue.Enqueue(Index));
		}

		TestFalse(TEXT("Full queues must not be empty"), Queue.IsEmpty());
		TestTrue(TEXT("Full queues must be full"), Queue.IsFull());
		TestFalse(TEXT("Adding to full queue must fail"), Queue.Enqueue(666));

		int32 Value;

		for (int32 Index = 0; Index < QueueSize - 1; ++Index)
		{
			TestTrue(TEXT("Peeking at a none-empty queue must succeed"), Queue.Peek(Value));
			TestEqual(TEXT("The peeked at value must be correct"), Value, Index);
			TestTrue(TEXT("Removing from a non-empty queue must succeed"), Queue.Dequeue(Value));
			TestEqual(TEXT("The removed value must be correct"), Value, Index);
		}

		TestTrue(TEXT("A queue that had all items removed must be empty"), Queue.IsEmpty());
		TestFalse(TEXT("A queue that had all items removed must not be full"), Queue.IsFull());
	}

	return true;
}
예제 #5
0
	void Test_PeriodicDamage()
	{
		const int32 NumPeriods = 10;
		const float PeriodSecs = 1.0f;
		const float DamagePerPeriod = 5.f; 
		const float StartingHealth = DestComponent->GetSet<UAbilitySystemTestAttributeSet>()->Health;

		// just try and reduce the health attribute
		{
			CONSTRUCT_CLASS(UGameplayEffect, BaseDmgEffect);
			AddModifier(BaseDmgEffect, GET_FIELD_CHECKED(UAbilitySystemTestAttributeSet, Health), EGameplayModOp::Additive, FScalableFloat(-DamagePerPeriod));
			BaseDmgEffect->DurationPolicy = EGameplayEffectDurationType::HasDuration;
			BaseDmgEffect->DurationMagnitude = FGameplayEffectModifierMagnitude(FScalableFloat(NumPeriods * PeriodSecs));
			BaseDmgEffect->Period.Value = PeriodSecs;

			SourceComponent->ApplyGameplayEffectToTarget(BaseDmgEffect, DestComponent, 1.f);
		}

		int32 NumApplications = 0;

		// Tick a small number to verify the application tick
		TickWorld(SMALL_NUMBER);
		++NumApplications;

		TestEqual(SKILL_TEST_TEXT("Health Reduced"), DestComponent->GetSet<UAbilitySystemTestAttributeSet>()->Health, StartingHealth - (DamagePerPeriod * NumApplications));

		// Tick a bit more to address possible floating point issues
		TickWorld(PeriodSecs * .1f);

		for (int32 i = 0; i < NumPeriods; ++i)
		{
			// advance time by one period
			TickWorld(PeriodSecs);

			++NumApplications;

			// check that health has been reduced
			TestEqual(SKILL_TEST_TEXT("Health Reduced"), DestComponent->GetSet<UAbilitySystemTestAttributeSet>()->Health, StartingHealth - (DamagePerPeriod * NumApplications));
		}

		// advance time by one extra period
		TickWorld(PeriodSecs);

		// should not have reduced further
		TestEqual(SKILL_TEST_TEXT("Health Reduced"), DestComponent->GetSet<UAbilitySystemTestAttributeSet>()->Health, StartingHealth - (DamagePerPeriod * NumApplications));

		// TODO: test that the effect is no longer applied
	}
const char* MockOLED::drawGeneralMock(String stringToPrint,MockOLED& obj) {
	const char* conversion;
	const char* smaller;
  conversion = stringToPrint.c_str();
	int printed = obj.MockPrintToOLED (conversion); //There's an interior method here that interacts with the OLED
	TestEqual ("drawGeneralPrintCheck", printed, 1 );
	return conversion;
}
예제 #7
0
	void Test_InstantDamageRemap()
	{
		const float DamageValue = 5.f;
		const float StartingHealth = DestComponent->GetSet<UAbilitySystemTestAttributeSet>()->Health;

		// This is the same as GameplayEffectsTest_InstantDamage but modifies the Damage attribute and confirms it is remapped to -Health by UAbilitySystemTestAttributeSet::PostAttributeModify
		{
			CONSTRUCT_CLASS(UGameplayEffect, BaseDmgEffect);
			AddModifier(BaseDmgEffect, GET_FIELD_CHECKED(UAbilitySystemTestAttributeSet, Damage), EGameplayModOp::Additive, FScalableFloat(DamageValue));
			BaseDmgEffect->DurationPolicy = EGameplayEffectDurationType::Instant;

			SourceComponent->ApplyGameplayEffectToTarget(BaseDmgEffect, DestComponent, 1.f);
		}

		// Now we should have lost some health
		TestEqual(SKILL_TEST_TEXT("Health Reduced"), DestComponent->GetSet<UAbilitySystemTestAttributeSet>()->Health, StartingHealth - DamageValue);

		// Confirm the damage attribute itself was reset to 0 when it was applied to health
		TestEqual(SKILL_TEST_TEXT("Damage Applied"), DestComponent->GetSet<UAbilitySystemTestAttributeSet>()->Damage, 0.f);
	}
예제 #8
0
void MockSDBeacon::writeToSD (String writeThisString, String fileName, MockSdFat& SD, MockFile& myFile) { //No good way to sensibly shorten
	const char* conversion = fileName.c_str();
	String printedThis;
	//Serial.println (conversion);
	//myFile = SD.open(conversion);
  if (myFile.available()) {
    printedThis = myFile.println(writeThisString);
    myFile.close();
  } 
	else {
    Serial.println(F("error opening example.txt"));
  }
	TestEqual ("writeToSD", printedThis, writeThisString);
}
예제 #9
0
int main(int argc, const char * argv[]) {
	auto obj = std::make_shared<HandShaking>();
	TestEqual(obj->countPerfect(2), 1);
	TestEqual(obj->countPerfect(4), 2);
	TestEqual(obj->countPerfect(6), 5);
	TestEqual(obj->countPerfect(8), 14);
	TestEqual(obj->countPerfect(10), 42);
	TestEqual(obj->countPerfect(16), 1430);
	
    return 0;
}
예제 #10
0
	void Test_InstantDamage()
	{
		const float DamageValue = 5.f;
		const float StartingHealth = DestComponent->GetSet<UAbilitySystemTestAttributeSet>()->Health;

		// just try and reduce the health attribute
		{
			
			CONSTRUCT_CLASS(UGameplayEffect, BaseDmgEffect);
			AddModifier(BaseDmgEffect, GET_FIELD_CHECKED(UAbilitySystemTestAttributeSet, Health), EGameplayModOp::Additive, FScalableFloat(-DamageValue));
			BaseDmgEffect->DurationPolicy = EGameplayEffectDurationType::Instant;
			
			SourceComponent->ApplyGameplayEffectToTarget(BaseDmgEffect, DestComponent, 1.f);
		}

		// make sure health was reduced
		TestEqual(SKILL_TEST_TEXT("Health Reduced"), DestComponent->GetSet<UAbilitySystemTestAttributeSet>()->Health, StartingHealth - DamageValue);
	}
bool FIntSerializationTest::RunTest (const FString& Parameters)
{
	//Create object for serialization
	//UIntSerialization SerializableObject;
	//SerializableObject->
	auto SerializableObject = NewObject<UIntSerialization>();
	SerializableObject->UnsignedInt8Variable = 255U;
	SerializableObject->UnsignedInt16Variable = 65535U;
	SerializableObject->UnsignedInt32Variable = 4294967295U;
	SerializableObject->UnsignedInt64Variable = 18446744073709551615U;
	SerializableObject->SignedInt8Variable = -128;
	SerializableObject->SignedInt16Variable = -32768;
	SerializableObject->SignedInt32Variable = 2147483647 ;
	SerializableObject->SignedInt64Variable = 9223372036854775807;
	//Serialize object
	//FArchive 
	//FMemoryWriter SerializedData = new FMemoryWriter(;

	TArray<uint8> SaveData;
	FMemoryWriter OutAr(SaveData, true);
	SerializableObject->Serialize(OutAr);

	//Deserialize into new object
	FMemoryReader InAr(SaveData, true);
	auto DeSerializableObject = NewObject<UIntSerialization>();
	DeSerializableObject->Serialize(InAr);

	//Compare test
	TestEqual(TEXT("int8 serialised and deserialised incorrectly"), SerializableObject->SignedInt8Variable, DeSerializableObject->SignedInt8Variable);
	TestEqual(TEXT("int16 serialised and deserialised incorrectly"), SerializableObject->SignedInt16Variable, DeSerializableObject->SignedInt16Variable);
	TestEqual(TEXT("int32 serialised and deserialised incorrectly"), SerializableObject->SignedInt32Variable, DeSerializableObject->SignedInt32Variable);
	TestEqual(TEXT("int64 serialised and deserialised incorrectly"), SerializableObject->SignedInt64Variable, DeSerializableObject->SignedInt64Variable);
	TestEqual(TEXT("uint8 serialised and deserialised incorrectly"), SerializableObject->UnsignedInt8Variable, DeSerializableObject->UnsignedInt8Variable);
	TestEqual(TEXT("uint16 serialised and deserialised incorrectly"), SerializableObject->UnsignedInt16Variable, DeSerializableObject->UnsignedInt16Variable);
	TestEqual(TEXT("uint32 serialised and deserialised incorrectly"), SerializableObject->UnsignedInt32Variable, DeSerializableObject->UnsignedInt32Variable);
	TestEqual(TEXT("uint64 serialised and deserialised incorrectly"), SerializableObject->UnsignedInt64Variable, DeSerializableObject->UnsignedInt64Variable);


	return true;
}
예제 #12
0
bool FLocContextTest::RunTest( const FString& Parameters )
{
	// Key metadata
	TSharedPtr< FLocMetadataObject > KeyMetadataA = MakeShareable( new FLocMetadataObject );
	TSharedPtr< FLocMetadataObject > KeyMetadataB = MakeShareable( new FLocMetadataObject );

	// Info metadata
	TSharedPtr< FLocMetadataObject > InfoMetadataA = MakeShareable( new FLocMetadataObject );
	TSharedPtr< FLocMetadataObject > InfoMetadataB = MakeShareable( new FLocMetadataObject );

	// Source metadata
	TSharedPtr< FLocMetadataObject > SourceMetadataA = MakeShareable( new FLocMetadataObject );
	TSharedPtr< FLocMetadataObject > SourceMetadataB = MakeShareable( new FLocMetadataObject );


	// Setup KeyMetadataA
	KeyMetadataA->SetStringField( TEXT("Gender"			),	TEXT("Masculine")	);
	KeyMetadataA->SetStringField( TEXT("Plurality"		),	TEXT("Singular")	);
	KeyMetadataA->SetStringField( TEXT("TargetGender"	),	TEXT("Masculine")	);
	KeyMetadataA->SetStringField( TEXT("TargetPlurality"),	TEXT("Singular")	);

	// Setup KeyMetadataB
	KeyMetadataB->SetStringField( TEXT("Gender"			),	TEXT("Masculine")	);
	KeyMetadataB->SetStringField( TEXT("Plurality"		),	TEXT("Singular")	);
	KeyMetadataB->SetStringField( TEXT("TargetGender"	),	TEXT("Feminine")	);
	KeyMetadataB->SetStringField( TEXT("TargetPlurality"),	TEXT("Singular")	);

	// Setup source metadata
	SourceMetadataA->SetBoolField( TEXT("*IsMature"), false );
	SourceMetadataB->SetBoolField( TEXT("*IsMature"), true );

	// Set InfoMetadataA
	InfoMetadataA->SetStringField( TEXT("VoiceActorDirection"), TEXT("Go big or go home!") );

	// Test FContext
	{
		FContext ContextA;
		ContextA.Key			= TEXT("KeyA");
		ContextA.SourceLocation = TEXT("SourceLocationA");
		ContextA.InfoMetadataObj = MakeShareable( new FLocMetadataObject(*InfoMetadataA) );
		ContextA.KeyMetadataObj = MakeShareable( new FLocMetadataObject(*KeyMetadataA) );

		FContext ContextB;
		ContextB.Key			= TEXT("KeyB");
		ContextB.SourceLocation = TEXT("SourceLocationB");
		ContextB.InfoMetadataObj = MakeShareable( new FLocMetadataObject(*InfoMetadataB) );
		ContextB.KeyMetadataObj = MakeShareable( new FLocMetadataObject(*KeyMetadataB) );


		// Test copy ctor
		{
			FContext ContextAClone = ContextA;

			if( ContextAClone.InfoMetadataObj == ContextA.InfoMetadataObj )
			{
				AddError(TEXT("FContext InfoMetadataObj and its Clone are not unique objects."));
			}

			if( ContextAClone.KeyMetadataObj == ContextA.KeyMetadataObj )
			{
				AddError(TEXT("FContext KeyMetadataObj and its Clone are not unique objects."));
			}

			TestEqual( TEXT("ContextAClone.Key == ContextA.Key"), ContextAClone.Key, ContextA.Key );
			TestEqual( TEXT("ContextAClone.SourceLocation == ContextA.SourceLocation"), ContextAClone.SourceLocation, ContextA.SourceLocation );
			TestEqual( TEXT("ContextAClone.bIsOptional == ContextA.bIsOptional"), ContextAClone.bIsOptional, ContextA.bIsOptional );
			TestTrue( TEXT("ContextAClone.InfoMetadataObj == ContextA.InfoMetadataObj"), *(ContextAClone.InfoMetadataObj) == *(ContextA.InfoMetadataObj) );
			TestTrue( TEXT("ContextAClone.KeyMetadataObj == ContextA.KeyMetadataObj"), *(ContextAClone.KeyMetadataObj) == *(ContextA.KeyMetadataObj) );

			TestEqual( TEXT("ContextAClone == ContextA"), ContextAClone, ContextA );
			TestFalse( TEXT("ContextAClone < ContextA"), ContextAClone < ContextA );

		}

		// Test assignment operator
		{
			FContext ContextAClone;
			ContextAClone = ContextA;

			if( ContextAClone.InfoMetadataObj == ContextA.InfoMetadataObj )
			{
				AddError(TEXT("FContext InfoMetadataObj and its Clone are not unique objects."));
			}

			if( ContextAClone.KeyMetadataObj == ContextA.KeyMetadataObj )
			{
				AddError(TEXT("FContext KeyMetadataObj and its Clone are not unique objects."));
			}

			TestEqual( TEXT("ContextAClone.Key == ContextA.Key"), ContextAClone.Key, ContextA.Key );
			TestEqual( TEXT("ContextAClone.SourceLocation == ContextA.SourceLocation"), ContextAClone.SourceLocation, ContextA.SourceLocation );
			TestEqual( TEXT("ContextAClone.bIsOptional == ContextA.bIsOptional"), ContextAClone.bIsOptional, ContextA.bIsOptional );
			TestTrue( TEXT("ContextAClone.InfoMetadataObj == ContextA.InfoMetadataObj"), *(ContextAClone.InfoMetadataObj) == *(ContextA.InfoMetadataObj) );
			TestTrue( TEXT("ContextAClone.KeyMetadataObj == ContextA.KeyMetadataObj"), *(ContextAClone.KeyMetadataObj) == *(ContextA.KeyMetadataObj) );

			TestEqual( TEXT("ContextAClone == ContextA"), ContextAClone, ContextA );
			TestFalse( TEXT("ContextAClone < ContextA"), ContextAClone < ContextA );
		}

		// Test comparison operator
		{
			// Key and KeyMetadataObj members should be the only items that are taken into account when comparing
			FContext ContextAClone = ContextA;
			TestEqual( TEXT("ContextAClone == ContextA"), ContextAClone, ContextA );

			// Arbitrarily change all the non-important members
			ContextAClone.SourceLocation = ContextA.SourceLocation + TEXT("New");
			ContextAClone.bIsOptional = !ContextA.bIsOptional;
			ContextAClone.InfoMetadataObj.Reset();
			ContextAClone.InfoMetadataObj = MakeShareable( new FLocMetadataObject( *InfoMetadataB ) );
			TestEqual( TEXT("ContextAClone == ContextA"), ContextAClone, ContextA );

			// Changing the key in any way will cause comparison to fail
			ContextAClone.Key = ContextAClone.Key + TEXT("New");
			TestNotEqual( TEXT("ContextAClone != ContextA"), ContextAClone, ContextA );

			// Reset and test KeyMetadataObj change to one of the value entries
			ContextAClone = ContextA;
			ContextAClone.KeyMetadataObj->SetStringField( TEXT("TargetPlurality"), TEXT("Plural") );
			TestNotEqual( TEXT("ContextAClone != ContextA"), ContextAClone, ContextA );

			// Reset and test addition of entry to KeyMetadataObj
			ContextAClone = ContextA;
			ContextAClone.KeyMetadataObj->SetStringField( TEXT("NewField"), TEXT("NewFieldValue") );
			TestNotEqual( TEXT("ContextAClone != ContextA"), ContextAClone, ContextA );

			// Reset and test removal of entry from KeyMetadataObj
			ContextAClone = ContextA;
			ContextAClone.KeyMetadataObj->RemoveField( TEXT("TargetPlurality") );
			TestNotEqual( TEXT("ContextAClone != ContextA"), ContextAClone, ContextA );

			// Context with valid but empty KeyMetadataObject should be equivalent to Context with null KeyMetadataObject
			FContext ContextEmptyA;
			FContext ContextEmptyB;
			ContextEmptyB.KeyMetadataObj = MakeShareable( new FLocMetadataObject );
			TestEqual( TEXT("ContextEmptyA == ContextEmptyB"), ContextEmptyA, ContextEmptyB );
		}

		// Testing less than operator
		{
			TestTrue( TEXT("ContextA < ContextB"), ContextA < ContextB );

			FContext ContextAClone = ContextA;

			// Differences in Key
			TestFalse( TEXT("ContextA < ContextAClone"), ContextA < ContextAClone );
			ContextAClone.Key = ContextAClone.Key + TEXT("A");
			//currently failing TestTrue( TEXT("ContextA < ContextAClone"), ContextA < ContextAClone );

			// Adding new key metadata entry that will appear before other entries
			ContextAClone = ContextA;
			ContextAClone.KeyMetadataObj->SetStringField( TEXT("ANewKey"), TEXT("ANewValue") );
			TestTrue( TEXT("ContextAClone < ContextA"), ContextAClone < ContextA );

			// Adding new key metadata entry that will appear after other entries
			ContextAClone = ContextA;
			ContextAClone.KeyMetadataObj->SetStringField( TEXT("ZNewKey"), TEXT("ZNewValue") );
			//currently failing TestTrue( TEXT("ContextA < ContextAClone"), ContextA < ContextAClone );

			// Removing a key metadata entry
			ContextAClone = ContextA;
			ContextAClone.KeyMetadataObj->RemoveField( TEXT("TargetPlurality") ) ;
			TestTrue( TEXT("ContextAClone < ContextA"), ContextAClone < ContextA );

			// Changing a key metadata entry value
			ContextAClone = ContextA;
			ContextAClone.KeyMetadataObj->SetStringField( TEXT("TargetPlurality"), TEXT("A") ) ;
			TestTrue( TEXT("ContextAClone < ContextA"), ContextAClone < ContextA );

			FContext ContextEmptyA;
			FContext ContextEmptyB;
			TestFalse( TEXT("ContextEmptyA < ContextEmptyB"), ContextEmptyA < ContextEmptyB );
			ContextEmptyB.KeyMetadataObj = MakeShareable( new FLocMetadataObject );
			TestFalse( TEXT("ContextEmptyA < ContextEmptyB"), ContextEmptyA < ContextEmptyB );
			TestFalse( TEXT("ContextEmptyB < ContextEmptyA"), ContextEmptyB < ContextEmptyA );
			ContextEmptyB.KeyMetadataObj->SetStringField(TEXT("AMetadataKey"), TEXT("AMetadataValue"));
			TestTrue( TEXT("ContextEmptyA < ContextEmptyB"), ContextEmptyA < ContextEmptyB );
		}
	}
	return true;
}
bool FTripleBufferTest::RunTest(const FString& Parameters)
{
	// uninitialized buffer
	{
		TTripleBuffer<int32> Buffer(NoInit);

		TestFalse(TEXT("Uninitialized triple buffer must not be dirty"), Buffer.IsDirty());
	}

	// initialized buffer
	{
		TTripleBuffer<int32> Buffer(1);

		TestFalse(TEXT("Initialized triple buffer must not be dirty"), Buffer.IsDirty());
		TestEqual(TEXT("Initialized triple buffer must have correct read buffer value"), Buffer.Read(), 1);

		Buffer.SwapReadBuffers();

		TestEqual(TEXT("Initialized triple buffer must have correct temp buffer value"), Buffer.Read(), 1);

		Buffer.SwapWriteBuffers();

		TestTrue(TEXT("Write buffer swap must set dirty flag"), Buffer.IsDirty());

		Buffer.SwapReadBuffers();

		TestFalse(TEXT("Read buffer swap must clear dirty flag"), Buffer.IsDirty());
		TestEqual(TEXT("Initialized triple buffer must have correct temp buffer value"), Buffer.Read(), 1);
	}

	// pre-set buffer
	{
		int32 Array[3] = { 1, 2, 3 };
		TTripleBuffer<int32> Buffer(Array);

		int32 Read = Buffer.Read();
		TestEqual(TEXT("Pre-set triple buffer must have correct Read buffer value"), Read, 3);

		Buffer.SwapReadBuffers();

		int32 Temp = Buffer.Read();
		TestEqual(TEXT("Pre-set triple buffer must have correct Temp buffer value"), Temp, 1);

		Buffer.SwapWriteBuffers();
		Buffer.SwapReadBuffers();

		int32 Write = Buffer.Read();
		TestEqual(TEXT("Pre-set triple buffer must have correct Write buffer value"), Write, 2);
	}

	// operations
	{
		TTripleBuffer<int32> Buffer;

		for (int32 Index = 0; Index < 6; ++Index)
		{
			int32& Write = Buffer.GetWriteBuffer(); Write = Index; Buffer.SwapWriteBuffers();
			Buffer.SwapReadBuffers();
			TestEqual(*FString::Printf(TEXT("Triple buffer must read correct value (%i)"), Index), Buffer.Read(), Index);
		}

		FRandomStream Rand;
		int32 LastRead = -1;

		for (int32 Index = 0; Index < 100; ++Index)
		{
			int32 Writes = Rand.GetUnsignedInt() % 4;

			while (Writes > 0)
			{
				int32& Write = Buffer.GetWriteBuffer(); Write = Index; Buffer.SwapWriteBuffers();
				--Writes;
			}
			
			int32 Reads = Rand.GetUnsignedInt() % 4;

			while (Reads > 0)
			{
				if (!Buffer.IsDirty())
				{
					break;
				}

				Buffer.SwapReadBuffers();
				int32 Read = Buffer.Read();
				TestTrue(TEXT("Triple buffer must read in increasing order"), Read > LastRead);
				LastRead = Read;
				--Reads;
			}
		}
	}

	return true;
}
예제 #14
0
bool FIPv4AddressTest::RunTest( const FString& Parameters )
{
	// component access must be correct
	FIPv4Address a1_1 = FIPv4Address(1, 2, 3, 4);

	TestEqual<uint8>(TEXT("Byte 0 of 1.2.3.4 must be 4"), a1_1.GetByte(0), 4);
	TestEqual<uint8>(TEXT("Byte 1 of 1.2.3.4 must be 3"), a1_1.GetByte(1), 3);
	TestEqual<uint8>(TEXT("Byte 2 of 1.2.3.4 must be 2"), a1_1.GetByte(2), 2);
	TestEqual<uint8>(TEXT("Byte 3 of 1.2.3.4 must be 1"), a1_1.GetByte(3), 1);

	// link local addresses must be recognized
	FIPv4Address a2_1 = FIPv4Address(169, 254, 0, 1);
	FIPv4Address a2_2 = FIPv4Address(168, 254, 0, 1);
	FIPv4Address a2_3 = FIPv4Address(169, 253, 0, 1);

	TestTrue(TEXT("169.254.0.1 must be a link local address"), a2_1.IsLinkLocal());
	TestFalse(TEXT("168.254.0.1 must not be a link local address"), a2_2.IsLinkLocal());
	TestFalse(TEXT("169.253.0.1 must not be a link local address"), a2_3.IsLinkLocal());

	// loopback addresses must be recognized
	FIPv4Address a3_1 = FIPv4Address(127, 0, 0, 1);
	FIPv4Address a3_2 = FIPv4Address(128, 0, 0, 1);

	TestTrue(TEXT("127.0.0.1 must be a loopback address"), a3_1.IsLoopbackAddress());
	TestFalse(TEXT("128.0.0.1 must not be a loopback address"), a3_2.IsLoopbackAddress());

	// multicast addresses must be recognized
	FIPv4Address a4_1 = FIPv4Address(223, 255, 255, 255);
	FIPv4Address a4_2 = FIPv4Address(224, 0, 0, 0);
	FIPv4Address a4_3 = FIPv4Address(239, 255, 255, 255);
	FIPv4Address a4_4 = FIPv4Address(240, 0, 0, 0);

	TestFalse(TEXT("223.255.255.255 must not be a multicast address"), a4_1.IsMulticastAddress());
	TestTrue(TEXT("224.0.0.0 must be a multicast address"), a4_2.IsMulticastAddress());
	TestTrue(TEXT("239.255.255.255 must be a multicast address"), a4_3.IsMulticastAddress());
	TestFalse(TEXT("240.0.0.0 must not be a multicast address"), a4_4.IsMulticastAddress());

	// string conversion
	FIPv4Address a5_1 = FIPv4Address(1, 2, 3, 4);

	TestEqual<FString>(TEXT("String conversion (1.2.3.4)"), a5_1.ToText().ToString(), TEXT("1.2.3.4"));

	// parsing valid strings must succeed
	FIPv4Address a6_1 = FIPv4Address(1, 2, 3, 4);
	FIPv4Address a6_2;

	TestTrue(TEXT("Parsing valid strings must succeed (1.2.3.4)"), FIPv4Address::Parse(TEXT("1.2.3.4"), a6_2));
	TestEqual(TEXT("Parsing valid strings must result in correct value (1.2.3.4)"), a6_2, a6_1);

	// parsing invalid strings must fail
	FIPv4Address a7_1;

	TestFalse(TEXT("Parsing invalid strings must fail (1.2.3)"), FIPv4Address::Parse(TEXT("1.2.3"), a6_2));

	// site local addresses must be recognized
	FIPv4Address a8_1 = FIPv4Address(10, 0, 0, 1);
	FIPv4Address a8_2 = FIPv4Address(172, 16, 0, 1);
	FIPv4Address a8_3 = FIPv4Address(192, 168, 0, 1);

	TestTrue(TEXT("10.0.0.1 must be a site local address"), a8_1.IsSiteLocalAddress());
	TestTrue(TEXT("172.16.0.1 must be a site local address"), a8_2.IsSiteLocalAddress());
	TestTrue(TEXT("192.168.0.1 must be a site local address"), a8_3.IsSiteLocalAddress());

	FIPv4Address a8_4 = FIPv4Address(11, 0, 0, 1);
	FIPv4Address a8_5 = FIPv4Address(173, 16, 0, 1);
	FIPv4Address a8_6 = FIPv4Address(172, 17, 0, 1);
	FIPv4Address a8_7 = FIPv4Address(193, 168, 0, 1);
	FIPv4Address a8_8 = FIPv4Address(192, 169, 0, 1);

	TestFalse(TEXT("11.0.0.1 must not be a site local address"), a8_4.IsSiteLocalAddress());
	TestFalse(TEXT("173.16.0.1 must not be a site local address"), a8_5.IsSiteLocalAddress());
	TestFalse(TEXT("172.17.0.1 must not be a site local address"), a8_6.IsSiteLocalAddress());
	TestFalse(TEXT("193.168.0.1 must not be a site local address"), a8_7.IsSiteLocalAddress());
	TestFalse(TEXT("192.169.0.1 must not be a site local address"), a8_8.IsSiteLocalAddress());

	return true;
}
bool FGuidTest::RunTest( const FString& Parameters )
{
	FGuid g = FGuid(305419896, 2271560481, 305419896, 2271560481);

	// string conversions
	TestEqual(TEXT("String conversion (Default) must return EGuidFormats::Digits string"), g.ToString(), g.ToString(EGuidFormats::Digits));
	TestEqual<FString>(TEXT("String conversion (EGuidFormats::Digits)"), g.ToString(EGuidFormats::Digits), TEXT("12345678876543211234567887654321"));
	TestEqual<FString>(TEXT("String conversion (EGuidFormats::DigitsWithHyphens)"), g.ToString(EGuidFormats::DigitsWithHyphens), TEXT("12345678-8765-4321-1234-567887654321"));
	TestEqual<FString>(TEXT("String conversion (EGuidFormats::DigitsWithHyphensInBraces)"), g.ToString(EGuidFormats::DigitsWithHyphensInBraces), TEXT("{12345678-8765-4321-1234-567887654321}"));
	TestEqual<FString>(TEXT("String conversion (EGuidFormats::DigitsWithHyphensInParentheses)"), g.ToString(EGuidFormats::DigitsWithHyphensInParentheses), TEXT("(12345678-8765-4321-1234-567887654321)"));
	TestEqual<FString>(TEXT("String conversion (EGuidFormats::HexValuesInBraces)"), g.ToString(EGuidFormats::HexValuesInBraces), TEXT("{0x12345678,0x8765,0x4321,{0x12,0x34,0x56,0x78,0x87,0x65,0x43,0x21}}"));
	TestEqual<FString>(TEXT("String conversion (EGuidFormats::UniqueObjectGuid)"), g.ToString(EGuidFormats::UniqueObjectGuid), TEXT("12345678-87654321-12345678-87654321"));

	// parsing valid strings (exact)
	FGuid g2_1;

	TestTrue(TEXT("Parsing valid strings must succeed (EGuidFormats::Digits)"), FGuid::ParseExact(TEXT("12345678876543211234567887654321"), EGuidFormats::Digits, g2_1));
	TestEqual(TEXT("Parsing valid strings must succeed (EGuidFormats::Digits)"), g2_1, g);

	TestTrue(TEXT("Parsing valid strings must succeed (EGuidFormats::DigitsWithHyphens)"), FGuid::ParseExact(TEXT("12345678-8765-4321-1234-567887654321"), EGuidFormats::DigitsWithHyphens, g2_1));
	TestEqual(TEXT("Parsing valid strings must succeed (EGuidFormats::DigitsWithHyphens)"), g2_1, g);

	TestTrue(TEXT("Parsing valid strings must succeed (EGuidFormats::DigitsWithHyphensInBraces)"), FGuid::ParseExact(TEXT("{12345678-8765-4321-1234-567887654321}"), EGuidFormats::DigitsWithHyphensInBraces, g2_1));
	TestEqual(TEXT("Parsing valid strings must succeed (EGuidFormats::DigitsWithHyphensInBraces)"), g2_1, g);

	TestTrue(TEXT("Parsing valid strings must succeed (EGuidFormats::DigitsWithHyphensInParentheses)"), FGuid::ParseExact(TEXT("(12345678-8765-4321-1234-567887654321)"), EGuidFormats::DigitsWithHyphensInParentheses, g2_1));
	TestEqual(TEXT("Parsing valid strings must succeed (EGuidFormats::DigitsWithHyphensInParentheses)"), g2_1, g);

	TestTrue(TEXT("Parsing valid strings must succeed (EGuidFormats::HexValuesInBraces)"), FGuid::ParseExact(TEXT("{0x12345678,0x8765,0x4321,{0x12,0x34,0x56,0x78,0x87,0x65,0x43,0x21}}"), EGuidFormats::HexValuesInBraces, g2_1));
	TestEqual(TEXT("Parsing valid strings must succeed (EGuidFormats::HexValuesInBraces)"), g2_1, g);

	TestTrue(TEXT("Parsing valid strings must succeed (EGuidFormats::UniqueObjectGuid)"), FGuid::ParseExact(TEXT("12345678-87654321-12345678-87654321"), EGuidFormats::UniqueObjectGuid, g2_1));
	TestEqual(TEXT("Parsing valid strings must succeed (EGuidFormats::UniqueObjectGuid)"), g2_1, g);

	// parsing invalid strings (exact)


	// parsing valid strings (automatic)
	FGuid g3_1;

	TestTrue(TEXT("Parsing valid strings must succeed (12345678876543211234567887654321)"), FGuid::Parse(TEXT("12345678876543211234567887654321"), g3_1));
	TestEqual(TEXT("Parsing valid strings must succeed (12345678876543211234567887654321)"), g3_1, g);

	TestTrue(TEXT("Parsing valid strings must succeed (12345678-8765-4321-1234-567887654321)"), FGuid::Parse(TEXT("12345678-8765-4321-1234-567887654321"), g3_1));
	TestEqual(TEXT("Parsing valid strings must succeed (12345678-8765-4321-1234-567887654321)"), g3_1, g);

	TestTrue(TEXT("Parsing valid strings must succeed ({12345678-8765-4321-1234-567887654321})"), FGuid::Parse(TEXT("{12345678-8765-4321-1234-567887654321}"), g3_1));
	TestEqual(TEXT("Parsing valid strings must succeed ({12345678-8765-4321-1234-567887654321})"), g3_1, g);

	TestTrue(TEXT("Parsing valid strings must succeed ((12345678-8765-4321-1234-567887654321))"), FGuid::Parse(TEXT("(12345678-8765-4321-1234-567887654321)"), g3_1));
	TestEqual(TEXT("Parsing valid strings must succeed ((12345678-8765-4321-1234-567887654321))"), g3_1, g);

	TestTrue(TEXT("Parsing valid strings must succeed ({0x12345678,0x8765,0x4321,{0x12,0x34,0x56,0x78,0x87,0x65,0x43,0x21}})"), FGuid::Parse(TEXT("{0x12345678,0x8765,0x4321,{0x12,0x34,0x56,0x78,0x87,0x65,0x43,0x21}}"), g3_1));
	TestEqual(TEXT("Parsing valid strings must succeed ({0x12345678,0x8765,0x4321,{0x12,0x34,0x56,0x78,0x87,0x65,0x43,0x21}})"), g3_1, g);

	TestTrue(TEXT("Parsing valid strings must succeed (12345678-87654321-12345678-87654321)"), FGuid::Parse(TEXT("12345678-87654321-12345678-87654321"), g3_1));
	TestEqual(TEXT("Parsing valid strings must succeed (12345678-87654321-12345678-87654321)"), g3_1, g);

	//parsing invalid strings (automatic)

	// GUID validation
	FGuid g4_1 = FGuid::NewGuid();

	TestTrue(TEXT("New GUIDs must be valid"), g4_1.IsValid());
	
	g4_1.Invalidate();

	TestFalse(TEXT("Invalidated GUIDs must be invalid"), g4_1.IsValid());

	return true;
}
예제 #16
0
bool FTimespanTest::RunTest( const FString& Parameters )
{
	// constructors must create equal objects
	FTimespan ts1_1 = FTimespan(3, 2, 1);
	FTimespan ts1_2 = FTimespan(0, 3, 2, 1);
	FTimespan ts1_3 = FTimespan(0, 3, 2, 1, 0);

	TestEqual(TEXT("Constructors must create equal objects (Hours/Minutes/Seconds vs. Days/Hours/Minutes/Seconds)"), ts1_1, ts1_2);
	TestEqual(TEXT("Constructors must create equal objects (Hours/Minutes/Seconds vs. Days/Hours/Minutes/Seconds/Milliseconds)"), ts1_1, ts1_3);

	// component getters must return correct values
	FTimespan ts2_1 = FTimespan(1, 2, 3, 4, 5);

	TestEqual(TEXT("Component getters must return correct values (Days)"), ts2_1.GetDays(), 1);
	TestEqual(TEXT("Component getters must return correct values (Hours)"), ts2_1.GetHours(), 2);
	TestEqual(TEXT("Component getters must return correct values (Minutes)"), ts2_1.GetMinutes(), 3);
	TestEqual(TEXT("Component getters must return correct values (Seconds)"), ts2_1.GetSeconds(), 4);
	TestEqual(TEXT("Component getters must return correct values (Milliseconds)"), ts2_1.GetMilliseconds(), 5);

	// durations of positive and negative time spans must match
	FTimespan ts3_1 = FTimespan(1, 2, 3, 4, 5);
	FTimespan ts3_2 = FTimespan(-1, -2, -3, -4, -5);

	TestEqual(TEXT("Durations of positive and negative time spans must match"), ts3_1.GetDuration(), ts3_2.GetDuration());

	// static constructors must create correct values
	TestEqual(TEXT("Static constructors must create correct values (FromDays)"), FTimespan::FromDays(123).GetTotalDays(), 123.0);
	TestEqual(TEXT("Static constructors must create correct values (FromHours)"), FTimespan::FromHours(123).GetTotalHours(), 123.0);
	TestEqual(TEXT("Static constructors must create correct values (FromMinutes)"), FTimespan::FromMinutes(123).GetTotalMinutes(), 123.0);
	TestEqual(TEXT("Static constructors must create correct values (FromSeconds)"), FTimespan::FromSeconds(123).GetTotalSeconds(), 123.0);
	TestEqual(TEXT("Static constructors must create correct values (FromMilliseconds)"), FTimespan::FromMilliseconds(123).GetTotalMilliseconds(), 123.0);

	// string conversions must return correct strings
	FTimespan ts5_1 = FTimespan(1, 2, 3, 4, 5);

	TestEqual<FString>(TEXT("String conversion (Default)"), ts5_1.ToString(), TEXT("1.02:03:04.005"));
	TestEqual<FString>(TEXT("String conversion (%n%d.%h:%m:%s.%f)"), ts5_1.ToString(TEXT("%n%d.%h:%m:%s.%f")), TEXT("1.02:03:04.005"));

	// parsing valid strings must succeed
	FTimespan ts6_1 = FTimespan(1, 2, 3, 4, 5);
	FTimespan ts6_2;

	TestTrue(TEXT("Parsing valid strings must succeed (1.02:03:04.005)"), FTimespan::Parse(TEXT("1.02:03:04.005"), ts6_2));
	TestEqual(TEXT("Parsing valid strings must result in correct values (1.02:03:04.005)"), ts6_2, ts6_1);

	// parsing invalid strings must fail
	FTimespan ts7_1;

	//TestFalse(TEXT("Parsing invalid strings must fail (1,02:03:04.005)"), FTimespan::Parse(TEXT("1,02:03:04.005"), ts7_1));
	//TestFalse(TEXT("Parsing invalid strings must fail (1.1.02:03:04:005)"), FTimespan::Parse(TEXT("1.1.02:03:04:005"), ts7_1));
	//TestFalse(TEXT("Parsing invalid strings must fail (04:005)"), FTimespan::Parse(TEXT("04:005"), ts7_1));

	return true;
}
예제 #17
0
bool FArchiveTest::RunTest( const FString& Parameters )
{
    // Key metadata
    TSharedPtr< FLocMetadataObject > KeyMetadataA = MakeShareable( new FLocMetadataObject );
    TSharedPtr< FLocMetadataObject > KeyMetadataB = MakeShareable( new FLocMetadataObject );

    // Source metadata
    TSharedPtr< FLocMetadataObject > SourceMetadataA = MakeShareable( new FLocMetadataObject );
    TSharedPtr< FLocMetadataObject > SourceMetadataB = MakeShareable( new FLocMetadataObject );


    // Setup KeyMetadataA
    KeyMetadataA->SetStringField( TEXT("Gender"			),	TEXT("Masculine")	);
    KeyMetadataA->SetStringField( TEXT("Plurality"		),	TEXT("Singular")	);
    KeyMetadataA->SetStringField( TEXT("TargetGender"	),	TEXT("Masculine")	);
    KeyMetadataA->SetStringField( TEXT("TargetPlurality"),	TEXT("Singular")	);

    // Setup KeyMetadataB
    KeyMetadataB->SetStringField( TEXT("Gender"			),	TEXT("Masculine")	);
    KeyMetadataB->SetStringField( TEXT("Plurality"		),	TEXT("Singular")	);
    KeyMetadataB->SetStringField( TEXT("TargetGender"	),	TEXT("Feminine")	);
    KeyMetadataB->SetStringField( TEXT("TargetPlurality"),	TEXT("Singular")	);

    // Setup source metadata
    SourceMetadataA->SetBoolField( TEXT("*IsMature"), false );
    SourceMetadataB->SetBoolField( TEXT("*IsMature"), true );

    // Setup source item
    FLocItem SourceA( TEXT("TextA") );
    SourceA.MetadataObj = MakeShareable( new FLocMetadataObject(*SourceMetadataA) );

    FLocItem Translation = SourceA;
    Translation.Text = TEXT("TranslatedTextA");

    FString TestNamespace = TEXT("TestNamespace");
    FString SourceAKey = TEXT("TextA");

    // Test entry add
    {
        bool TestOptionalTrue = true;
        bool TestOptionalFalse = false;

        // bIsOptional is not used as a key.  We ensure adding entries where the bIsOptional member is the only difference works as expected.
        FInternationalizationArchive TestArchive;
        TestArchive.AddEntry( TestNamespace, SourceAKey, SourceA, Translation, NULL, TestOptionalTrue );
        // Add duplicate entry that differs in bIsOptional flag.  This add should report success because we already have an entry with matching
        //  namespace/source/keymetadata.  Differences in bIsOptional are not taken into consideration.
        bool bResult = TestArchive.AddEntry( TestNamespace, SourceAKey, SourceA, Translation, NULL, TestOptionalFalse );
        TestTrue( TEXT("AddEntry result = true"), bResult);

        // We should only have one entry in the archive
        int32 EntryCount = 0;
        for(auto Iter = TestArchive.GetEntriesBySourceTextIterator(); Iter; ++Iter, ++EntryCount);
        TestEqual( TEXT("EntryCount == 1"), EntryCount, 1 );

        // Make sure the original bIsOptional value is not overwritten by our second add.
        TSharedPtr< FArchiveEntry > FoundEntry = TestArchive.FindEntryByKey( TestNamespace, SourceAKey, NULL );
        if( !FoundEntry.IsValid() )
        {
            AddError(TEXT("FArchiveEntry could not find entry using FindEntryByKey."));
        }
        else
        {
            TestTrue( TEXT("FoundEntry->Namespace == Namespace"), FoundEntry->bIsOptional == TestOptionalTrue );
        }
    }

    // Test lookup an entry
    {
        {
            FInternationalizationArchive TestArchive;
            TestArchive.AddEntry( TestNamespace, SourceAKey, SourceA, Translation, KeyMetadataA, false );

            TSharedPtr< FArchiveEntry > FoundEntry = TestArchive.FindEntryByKey( TestNamespace, SourceAKey, KeyMetadataA );
            if( !FoundEntry.IsValid() )
            {
                AddError(TEXT("FArchiveEntry could not find entry using FindEntryByKey."));
            }
            else
            {
                TestTrue( TEXT("FoundEntry->Namespace == Namespace"), FoundEntry->Namespace == TestNamespace );
                TestTrue( TEXT("FoundEntry->Source == Source"), FoundEntry->Source == SourceA );
                TestTrue( TEXT("FoundEntry->Translation == Translation"), FoundEntry->Translation == Translation );
                if( FoundEntry->KeyMetadataObj == KeyMetadataA )
                {
                    AddError(TEXT("FArchiveEntry KeyMetadataObj is not a unique object."));
                }
                TestTrue( TEXT("FoundEntry->KeyMetadataObj == KeyMetadataA"), *(FoundEntry->KeyMetadataObj) == *(KeyMetadataA) );
            }

            // Passing in a mismatched key metadata will fail to find the entry.  Any fallback logic is intended to happen at runtime
            FoundEntry = TestArchive.FindEntryByKey( TestNamespace, SourceAKey, NULL );
            TestInvalid( TEXT("!FoundEntry.IsValid()"), FoundEntry);

            FoundEntry = TestArchive.FindEntryByKey( TestNamespace, SourceAKey, MakeShareable( new FLocMetadataObject() ) );
            TestInvalid( TEXT("!FoundEntry.IsValid()"), FoundEntry);

            FoundEntry = TestArchive.FindEntryByKey( TestNamespace, SourceAKey, KeyMetadataB );
            TestInvalid( TEXT("!FoundEntry.IsValid()"), FoundEntry);
        }

        // Ensure we can properly lookup entries with non-null but empty key metadata
        {
            FInternationalizationArchive TestArchive;
            TestArchive.AddEntry( TestNamespace, SourceAKey, SourceA, Translation, MakeShareable( new FLocMetadataObject() ), false );

            TSharedPtr< FArchiveEntry > FoundEntry = TestArchive.FindEntryByKey( TestNamespace, SourceAKey, NULL );
            if( !FoundEntry.IsValid() )
            {
                AddError(TEXT("FArchiveEntry could not find entry using FindEntryByKey."));
            }
            else
            {
                TestTrue( TEXT("FoundEntry->Namespace == Namespace"), FoundEntry->Namespace == TestNamespace );
                TestTrue( TEXT("FoundEntry->Source == Source"), FoundEntry->Source == SourceA );
            }
        }

        // Ensure we can properly lookup entries with null key metadata
        {
            FInternationalizationArchive TestArchive;
            TestArchive.AddEntry( TestNamespace, SourceAKey, SourceA, Translation, NULL, false );

            TSharedPtr< FArchiveEntry > FoundEntry = TestArchive.FindEntryByKey( TestNamespace, SourceAKey, NULL );
            if( !FoundEntry.IsValid() )
            {
                AddError(TEXT("FArchiveEntry could not find entry using FindEntryByKey."));
            }
            else
            {
                TestTrue( TEXT("FoundEntry->Namespace == Namespace"), FoundEntry->Namespace == TestNamespace );
                TestTrue( TEXT("FoundEntry->Source == Source"), FoundEntry->Source == SourceA );
            }

            // Test lookup with non-null but empty key metadata
            FoundEntry = TestArchive.FindEntryByKey( TestNamespace, SourceAKey, MakeShareable( new FLocMetadataObject() ) );
            if( !FoundEntry.IsValid() )
            {
                AddError(TEXT("FArchiveEntry could not find entry using FindEntryByKey."));
            }
            else
            {
                TestTrue( TEXT("FoundEntry->Namespace == Namespace"), FoundEntry->Namespace == TestNamespace );
                TestTrue( TEXT("FoundEntry->Source == Source"), FoundEntry->Source == SourceA );
            }
        }

        // Ensure lookup where source metadata has * prefixed entries work as expected.  Note: The source metadata object
        //   supports a * prefix on metadata names which modifies the way we perform metadata comparison(ignores entry type and value, only name is checked)
        {
            FLocItem SourceCompare( TEXT("TextA") );
            SourceCompare.MetadataObj = MakeShareable( new FLocMetadataObject() );
            SourceCompare.MetadataObj->SetStringField( TEXT("*IsMature"), TEXT("") );

            FInternationalizationArchive TestArchive;
            // Added entry with String *IsMature entry
            TestArchive.AddEntry( TestNamespace, SourceAKey, SourceCompare, Translation, KeyMetadataA, false );

            // Finding entry using a source that has Boolean *IsMature
            TSharedPtr< FArchiveEntry > FoundEntry = TestArchive.FindEntryByKey( TestNamespace, SourceAKey, KeyMetadataA );
            if( !FoundEntry.IsValid() )
            {
                AddError(TEXT("FArchiveEntry could not find entry using FindEntryByKey."));
            }
            else
            {
                TestTrue( TEXT("FoundEntry->Namespace == Namespace"), FoundEntry->Namespace == TestNamespace );
                TestTrue( TEXT("FoundEntry->Source == Source"), FoundEntry->Source == SourceA );
            }

            // Attempting to add an entry that only differs by a * prefexed source metadata entry value or type will result in success since
            //  a 'matching' entry already exists in the archive.  We should, however, only have one entry in the archive
            bool bResult = TestArchive.AddEntry( TestNamespace, SourceAKey, SourceA, Translation, KeyMetadataA, false );

            TestTrue( TEXT("AddEntry result = true"), bResult);

            // We should only have one entry in the archive
            int32 EntryCount = 0;
            for(auto Iter = TestArchive.GetEntriesBySourceTextIterator(); Iter; ++Iter, ++EntryCount);
            TestEqual( TEXT("EntryCount == 1"), EntryCount, 1 );

            // Check to see that the original type/value of the * prefixed entry did not get modified
            FoundEntry = TestArchive.FindEntryByKey( TestNamespace, SourceAKey, KeyMetadataA );
            if( !FoundEntry.IsValid() )
            {
                AddError(TEXT("FArchiveEntry could not find entry using FindEntryByKey."));
            }
            else
            {
                if( FoundEntry->Source.MetadataObj->HasTypedField< ELocMetadataType::String >( TEXT("*IsMature") ) )
                {
                    TestTrue( TEXT("Metadata Type == String and Value == Empty string"), FoundEntry->Source.MetadataObj->GetStringField( TEXT("*IsMature") ) == TEXT("") );
                }
                else
                {
                    AddError(TEXT("FArchiveEntry * prefixed metadata entry on source object was modified unexpectedly."));
                }
            }
        }
    }

    return true;
}
예제 #18
0
bool FLocItemTest::RunTest( const FString& Parameters )
{
	// Key metadata
	TSharedPtr< FLocMetadataObject > KeyMetadataA = MakeShareable( new FLocMetadataObject );
	TSharedPtr< FLocMetadataObject > KeyMetadataB = MakeShareable( new FLocMetadataObject );

	// Info metadata
	TSharedPtr< FLocMetadataObject > InfoMetadataA = MakeShareable( new FLocMetadataObject );
	TSharedPtr< FLocMetadataObject > InfoMetadataB = MakeShareable( new FLocMetadataObject );

	// Source metadata
	TSharedPtr< FLocMetadataObject > SourceMetadataA = MakeShareable( new FLocMetadataObject );
	TSharedPtr< FLocMetadataObject > SourceMetadataB = MakeShareable( new FLocMetadataObject );


	// Setup KeyMetadataA
	KeyMetadataA->SetStringField( TEXT("Gender"			),	TEXT("Masculine")	);
	KeyMetadataA->SetStringField( TEXT("Plurality"		),	TEXT("Singular")	);
	KeyMetadataA->SetStringField( TEXT("TargetGender"	),	TEXT("Masculine")	);
	KeyMetadataA->SetStringField( TEXT("TargetPlurality"),	TEXT("Singular")	);

	// Setup KeyMetadataB
	KeyMetadataB->SetStringField( TEXT("Gender"			),	TEXT("Masculine")	);
	KeyMetadataB->SetStringField( TEXT("Plurality"		),	TEXT("Singular")	);
	KeyMetadataB->SetStringField( TEXT("TargetGender"	),	TEXT("Feminine")	);
	KeyMetadataB->SetStringField( TEXT("TargetPlurality"),	TEXT("Singular")	);

	// Setup source metadata
	SourceMetadataA->SetBoolField( TEXT("*IsMature"), false );
	SourceMetadataB->SetBoolField( TEXT("*IsMature"), true );

	// Set InfoMetadataA
	InfoMetadataA->SetStringField( TEXT("VoiceActorDirection"), TEXT("Go big or go home!") );


	// Test FLocItem
	{
		FLocItem LocItemA( TEXT("TextA") );
		LocItemA.MetadataObj = MakeShareable( new FLocMetadataObject(*SourceMetadataA) );

		FLocItem LocItemB( TEXT("TextB") );
		LocItemB.MetadataObj = MakeShareable( new FLocMetadataObject(*SourceMetadataB) );

		// Test copy ctor
		{
			FLocItem LocItemAClone = LocItemA;

			if( LocItemAClone.MetadataObj == LocItemA.MetadataObj )
			{
				AddError(TEXT("FLocItem MetadataObj and its Clone are not unique objects."));
			}

			TestEqual( TEXT("LocItemAClone.Text == LocItemA.Text"), LocItemAClone.Text, LocItemA.Text );
			TestTrue( TEXT("LocItemAClone.MetadataObj == LocItemA.MetadataObj"), *(LocItemAClone.MetadataObj) == *(LocItemA.MetadataObj) );

			TestEqual( TEXT("LocItemAClone == LocItemA"), LocItemAClone, LocItemA );
			TestFalse( TEXT("LocItemAClone < LocItemA"), LocItemAClone < LocItemA );

		}

		// Test assignment operator
		{
			FLocItem LocItemAClone( TEXT("New") );

			LocItemAClone = LocItemA;

			if( LocItemAClone.MetadataObj == LocItemA.MetadataObj )
			{
				AddError(TEXT("FLocItem MetadataObj and its Clone are not unique objects."));
			}

			TestEqual( TEXT("LocItemAClone.Text == LocItemA.Text"), LocItemAClone.Text, LocItemA.Text );
			TestTrue( TEXT("LocItemAClone.MetadataObj == LocItemA.MetadataObj"), *(LocItemAClone.MetadataObj) == *(LocItemA.MetadataObj) );

			TestEqual( TEXT("LocItemAClone == LocItemA"), LocItemAClone, LocItemA );
			TestFalse( TEXT("LocItemAClone < LocItemA"), LocItemAClone < LocItemA );
			TestFalse( TEXT("LocItemA < LocItemAClone"), LocItemA < LocItemAClone );
		}

		// Test comparison operator
		{
			// Text and MetadataObj members should both be taken into account when comparing.  Note, Metadata supports a special * name prefix that causes the type 
			//   and value of the metadata to be ignored when performing comparisons
			FLocItem LocItemAClone = LocItemA;
			TestEqual( TEXT("LocItemAClone == LocItemA"), LocItemAClone, LocItemA );

			// Metadata with * prefix does not impact comparison but both FLocItems need a metadata where the name matches( type and value can be different )
			FLocItem LocItemAClone2 = LocItemA;
			LocItemAClone.MetadataObj->SetStringField( TEXT("*NewNonCompare"), TEXT("NewNonCompareValue") );
			TestNotEqual( TEXT("LocItemAClone != LocItemAClone2"), LocItemAClone, LocItemAClone2 );

			LocItemAClone2.MetadataObj->SetStringField( TEXT("*NewNonCompare"), TEXT("NewNonCompareValue2") );
			TestEqual( TEXT("LocItemAClone == LocItemAClone2"), LocItemAClone, LocItemAClone2 );

			// Changing the text in any way will cause comparison to fail
			LocItemAClone = LocItemA;
			LocItemAClone.Text = LocItemAClone.Text + TEXT("New");
			TestNotEqual( TEXT("LocItemAClone != LocItemA"), LocItemAClone, LocItemA );

			// LocItem with valid but empty KeyMetadataObject should be equivalent to LocItem with null KeyMetadataObject
			FLocItem LocItemEmptyA(TEXT("TestText"));
			FLocItem LocItemEmptyB(TEXT("TestText"));
			LocItemEmptyB.MetadataObj = MakeShareable( new FLocMetadataObject );
			TestEqual( TEXT("LocItemEmptyA == LocItemEmptyB"), LocItemEmptyA, LocItemEmptyB );
		}

		// Testing less than operator
		{
			TestTrue( TEXT("LocItemA < LocItemB"), LocItemA < LocItemB );
			TestFalse( TEXT("LocItemB < LocItemA"), LocItemB < LocItemA );

			FLocItem LocItemAClone = LocItemA;

			// Differences in Text
			TestFalse( TEXT("LocItemA < LocItemAClone"), LocItemA < LocItemAClone );
			LocItemAClone.Text = LocItemAClone.Text + TEXT("A");
			TestFalse( TEXT("LocItemAClone < LocItemA"), LocItemAClone < LocItemA );
			//currently failing TestTrue( TEXT("LocItemA < LocItemAClone"), LocItemA < LocItemAClone );

			// Adding new key metadata entry
			LocItemAClone = LocItemA;
			LocItemAClone.MetadataObj->SetStringField( TEXT("ANewKey"), TEXT("ANewValue") );
			//currently failing TestTrue( TEXT("LocItemA < LocItemAClone"), LocItemA < LocItemAClone );
			TestFalse( TEXT("LocItemAClone < LocItemA"), LocItemAClone < LocItemA );

			// Removing a key metadata entry
			LocItemAClone = LocItemA;
			LocItemAClone.MetadataObj->RemoveField( TEXT("*IsMature") );
			TestTrue( TEXT("LocItemAClone < LocItemA"), LocItemAClone < LocItemA );
			TestFalse( TEXT("LocItemA < LocItemAClone"), LocItemA < LocItemAClone );

			// Changing a key metadata entry value
			LocItemAClone = LocItemA;
			LocItemAClone.MetadataObj->SetBoolField( TEXT("*IsMature"),true );
			//currently failing TestTrue( TEXT("LocItemA < LocItemAClone"), LocItemA < LocItemAClone );
			TestFalse( TEXT("LocItemAClone < LocItemA"), LocItemAClone < LocItemA );

			// Test null and non-null but empty Metadata
			FLocItem LocItemEmptyA( TEXT("SameText") );
			FLocItem LocItemEmptyB( TEXT("SameText") );
			TestFalse( TEXT("LocItemEmptyA < LocItemEmptyB"), LocItemEmptyA < LocItemEmptyB );
			LocItemEmptyB.MetadataObj = MakeShareable( new FLocMetadataObject );
			TestFalse( TEXT("LocItemEmptyA < LocItemEmptyB"), LocItemEmptyA < LocItemEmptyB );
			TestFalse( TEXT("LocItemEmptyB < LocItemEmptyA"), LocItemEmptyB < LocItemEmptyA );
			LocItemEmptyB.MetadataObj->SetStringField(TEXT("AMetadataKey"), TEXT("AMetadataValue"));
			TestTrue( TEXT("LocItemEmptyA < LocItemEmptyB"), LocItemEmptyA < LocItemEmptyB );
		}
	}
	return true;
}
예제 #19
0
bool FManifestTest::RunTest( const FString& Parameters )
{
	// Key metadata
	TSharedPtr< FLocMetadataObject > KeyMetadataA = MakeShareable( new FLocMetadataObject );
	TSharedPtr< FLocMetadataObject > KeyMetadataB = MakeShareable( new FLocMetadataObject );

	// Info metadata
	TSharedPtr< FLocMetadataObject > InfoMetadataA = MakeShareable( new FLocMetadataObject );
	TSharedPtr< FLocMetadataObject > InfoMetadataB = MakeShareable( new FLocMetadataObject );

	// Source metadata
	TSharedPtr< FLocMetadataObject > SourceMetadataA = MakeShareable( new FLocMetadataObject );
	TSharedPtr< FLocMetadataObject > SourceMetadataB = MakeShareable( new FLocMetadataObject );


	// Setup KeyMetadataA
	KeyMetadataA->SetStringField( TEXT("Gender"			),	TEXT("Masculine")	);
	KeyMetadataA->SetStringField( TEXT("Plurality"		),	TEXT("Singular")	);
	KeyMetadataA->SetStringField( TEXT("TargetGender"	),	TEXT("Masculine")	);
	KeyMetadataA->SetStringField( TEXT("TargetPlurality"),	TEXT("Singular")	);

	// Setup KeyMetadataB
	KeyMetadataB->SetStringField( TEXT("Gender"			),	TEXT("Masculine")	);
	KeyMetadataB->SetStringField( TEXT("Plurality"		),	TEXT("Singular")	);
	KeyMetadataB->SetStringField( TEXT("TargetGender"	),	TEXT("Feminine")	);
	KeyMetadataB->SetStringField( TEXT("TargetPlurality"),	TEXT("Singular")	);

	// Setup source metadata
	SourceMetadataA->SetBoolField( TEXT("*IsMature"), false );
	SourceMetadataB->SetBoolField( TEXT("*IsMature"), true );

	// Set InfoMetadataA
	InfoMetadataA->SetStringField( TEXT("VoiceActorDirection"), TEXT("Go big or go home!") );

	// Test FInternationalizationManifest
	{
		FContext ContextA;
		ContextA.Key			= TEXT("KeyA");
		ContextA.SourceLocation = TEXT("SourceLocationA");
		ContextA.InfoMetadataObj = MakeShareable( new FLocMetadataObject(*InfoMetadataA) );
		ContextA.KeyMetadataObj = MakeShareable( new FLocMetadataObject(*KeyMetadataA) );

		FContext ContextB;
		ContextB.Key			= TEXT("KeyB");
		ContextB.SourceLocation = TEXT("SourceLocationB");
		ContextB.InfoMetadataObj = MakeShareable( new FLocMetadataObject(*InfoMetadataB) );
		ContextB.KeyMetadataObj = MakeShareable( new FLocMetadataObject(*KeyMetadataB) );

		FLocItem Source( TEXT("TestText") );
		Source.MetadataObj = MakeShareable( new FLocMetadataObject(*SourceMetadataA) );

		FString TestNamespace = TEXT("TestNamespace");


		// Adding entries with exactly matching Source and matching Context
		{
			FInternationalizationManifest TestManifest;

			TestManifest.AddSource( TestNamespace, Source, ContextA );
			bool bResult = TestManifest.AddSource( TestNamespace, Source, ContextA );

			// Adding a duplicate entry reports success but our entry count is not increased after the first entry is added
			TestTrue( TEXT("AddSource result == true"), bResult);
			TestEqual( TEXT("ManifestCount == 1"), CountManifestEntries(TestManifest), 1 );
		}

		// Adding entries with exactly matching Source but different Contexts
		{
			FInternationalizationManifest TestManifest;

			TestManifest.AddSource( TestNamespace, Source, ContextA );
			TestManifest.AddSource( TestNamespace, Source, ContextB );

			TestEqual( TEXT("ManifestCount == 2"), CountManifestEntries(TestManifest), 2 );

			// Test find by context
			TSharedPtr< FManifestEntry > FoundEntry1 = TestManifest.FindEntryByContext( TestNamespace, ContextA );
			if( !FoundEntry1.IsValid() )
			{
				AddError(TEXT("FManifestEntry could not find entry using FindEntryByContext."));
			}
			else
			{
				TestTrue( TEXT("FoundEntry->Source == Source"), FoundEntry1->Source == Source );
				TestEqual( TEXT("FoundEntry->Context.Num() == 2"), FoundEntry1->Contexts.Num(), 2);
			}

			TSharedPtr< FManifestEntry > FoundEntry2 = TestManifest.FindEntryByContext( TestNamespace, ContextB );
			if( !FoundEntry2.IsValid() )
			{
				AddError(TEXT("FManifestEntry could not find entry using FindEntryByContext."));
			}
			else
			{
				TestTrue( TEXT("FoundEntry->Source == Source"), FoundEntry2->Source == Source );
				TestEqual( TEXT("FoundEntry->Context.Num() == 2"), FoundEntry2->Contexts.Num(), 2);
			}

			// Test find by source
			TSharedPtr< FManifestEntry > FoundEntry3 = TestManifest.FindEntryBySource( TestNamespace, Source );
			if( !FoundEntry3.IsValid() )
			{
				AddError(TEXT("FManifestEntry could not find entry using FindEntryBySource."));
			}
			else
			{
				TestTrue( TEXT("FoundEntry->Source == Source"), FoundEntry3->Source == Source );
				TestEqual( TEXT("FoundEntry->Context.Num() == 2"), FoundEntry3->Contexts.Num(), 2);
			}

			TestTrue( TEXT("FoundEntry1 == FoundEntry2 == FoundEntry3"), (FoundEntry1 == FoundEntry2) && (FoundEntry1 == FoundEntry3) );

		}



		// Adding entries with Source that is NOT an exact match and matching context
		{
			// Source mismatched by Source Text.
			{
				FInternationalizationManifest TestManifest;

				FLocItem ConflictingSourceA( TEXT("Conflicting TestTextA") );
				FLocItem ConflictingSourceB( TEXT("Conflicting TestTextB") );

				TestManifest.AddSource( TestNamespace, ConflictingSourceA, ContextA );
				bool bResult = TestManifest.AddSource( TestNamespace, ConflictingSourceB, ContextA );

				// Adding the second entry reports failure and entry count is not increased
				TestFalse( TEXT("AddSource result == false"), bResult);
				TestEqual( TEXT("ManifestCount == 1"), CountManifestEntries(TestManifest), 1 );	
			}

			// Source mismatched by standard metadata type (not * prefixed) 
			{
				FInternationalizationManifest ManifestTypeConflict;

				FLocItem ConflictingSourceMetadataTypeA = Source;
				FLocItem ConflictingSourceMetadataTypeB = Source;

				// Set metadata with the same name but different type
				ConflictingSourceMetadataTypeA.MetadataObj->SetBoolField( TEXT("ConflictingType"), true );
				ConflictingSourceMetadataTypeB.MetadataObj->SetStringField( TEXT("ConflictingType"), TEXT("true") );

				ManifestTypeConflict.AddSource( TestNamespace, ConflictingSourceMetadataTypeA, ContextA );
				bool bResult = ManifestTypeConflict.AddSource( TestNamespace, ConflictingSourceMetadataTypeB, ContextA );

				TestFalse( TEXT("AddSource result == false"), bResult);
				TestEqual( TEXT("ManifestCount == 1"), CountManifestEntries(ManifestTypeConflict), 1 );

				// Should not find a match when searching with the second Source we tried to add
				TSharedPtr< FManifestEntry > FoundEntry = ManifestTypeConflict.FindEntryBySource( TestNamespace, ConflictingSourceMetadataTypeB );
				TestInvalid( TEXT("FoundEntry is not valid"), FoundEntry);

			}

			// Source mismatched by standard metadata value (not * prefixed)
			{
				FInternationalizationManifest TestManifest;

				FLocItem ConflictingSourceMetadataValueA = Source;
				FLocItem ConflictingSourceMetadataValueB = Source;

				// Set metadata with the same name and type but different value
				ConflictingSourceMetadataValueA.MetadataObj->SetStringField( TEXT("ConflictingValue"), TEXT("A") );
				ConflictingSourceMetadataValueB.MetadataObj->SetStringField( TEXT("ConflictingValue"), TEXT("B") );

				TestManifest.AddSource( TestNamespace, ConflictingSourceMetadataValueA, ContextA );
				bool bResult = TestManifest.AddSource( TestNamespace, ConflictingSourceMetadataValueB, ContextA );

				TestFalse( TEXT("AddSource result == false"), bResult);
				TestEqual( TEXT("ManifestCount == 1"), CountManifestEntries(TestManifest), 1 );

				// Should not find a match when searching with the second Source we tried to add
				TSharedPtr< FManifestEntry > FoundEntry = TestManifest.FindEntryBySource( TestNamespace, ConflictingSourceMetadataValueB );
				TestInvalid( TEXT("FoundEntry is not valid"), FoundEntry);

			}

			// Source mismatched by * prefixed metadata type
			{
				FInternationalizationManifest TestManifest;

				FLocItem ConflictingSourceMetadataTypeA = Source;
				FLocItem ConflictingSourceMetadataTypeB = Source;

				// Set metadata with the same name but different type
				ConflictingSourceMetadataTypeA.MetadataObj->SetBoolField( TEXT("*ConflictingType"), true );
				ConflictingSourceMetadataTypeB.MetadataObj->SetStringField( TEXT("*ConflictingType"), TEXT("true") );

				TestManifest.AddSource( TestNamespace, ConflictingSourceMetadataTypeA, ContextA );

				// Though the Source items are considered to be a match(they are equal) in this case, the manifest reports this as a conflict
				//  and should not add an entry.  The reason is that AddSource does an 'exact' match check on the metadata object
				bool bResult = TestManifest.AddSource( TestNamespace, ConflictingSourceMetadataTypeB, ContextA );

				TestFalse( TEXT("AddSource result == false"), bResult);
				TestEqual( TEXT("ManifestCount == 1"), CountManifestEntries(TestManifest), 1 );

				// We should be able to find the entry using either Source FLocItem
				TSharedPtr< FManifestEntry > FoundEntry1 = TestManifest.FindEntryBySource( TestNamespace, ConflictingSourceMetadataTypeA );
				TestValid( TEXT("FoundEntry1 is valid"), FoundEntry1);

				TSharedPtr< FManifestEntry > FoundEntry2 = TestManifest.FindEntryBySource( TestNamespace, ConflictingSourceMetadataTypeB );
				TestValid( TEXT("FoundEntry2 is valid"), FoundEntry2);


			}

			// Source mismatched by * prefixed metadata value
			{
				FInternationalizationManifest TestManifest;

				FLocItem ConflictingSourceMetadataValueA = Source;
				FLocItem ConflictingSourceMetadataValueB = Source;

				// Set metadata with the same name and type but different value
				ConflictingSourceMetadataValueA.MetadataObj->SetStringField( TEXT("*ConflictingValue"), TEXT("A") );
				ConflictingSourceMetadataValueB.MetadataObj->SetStringField( TEXT("*ConflictingValue"), TEXT("B") );

				TestManifest.AddSource( TestNamespace, ConflictingSourceMetadataValueA, ContextA );

				// Thought the Source items are considered to be a match(they are equal) in this case, the manifest reports this as a conflict
				//  and should not add an entry.  The reason is that AddSource does an 'exact' match check on the metadata object
				bool bResult = TestManifest.AddSource( TestNamespace, ConflictingSourceMetadataValueB, ContextA );

				TestFalse( TEXT("AddSource result == false"), bResult);
				TestEqual( TEXT("ManifestCount == 1"), CountManifestEntries(TestManifest), 1 );

				// We should be able to find the entry using either Source FLocItem
				TSharedPtr< FManifestEntry > FoundEntry1 = TestManifest.FindEntryBySource( TestNamespace, ConflictingSourceMetadataValueA );
				TestValid( TEXT("FoundEntry1 is valid"), FoundEntry1);

				TSharedPtr< FManifestEntry > FoundEntry2 = TestManifest.FindEntryBySource( TestNamespace, ConflictingSourceMetadataValueB );
				TestValid( TEXT("FoundEntry2 is valid"), FoundEntry2);

			}

		}

		// Adding entries with Source that is NOT an exact match and different context
		{
			// Source mismatched by Source Text.
			{
				FInternationalizationManifest TestManifest;

				FLocItem ConflictingSourceA( TEXT("Conflicting TestTextA") );
				FLocItem ConflictingSourceB( TEXT("Conflicting TestTextB") );

				TestManifest.AddSource( TestNamespace, ConflictingSourceA, ContextA );
				bool bResult = TestManifest.AddSource( TestNamespace, ConflictingSourceB, ContextB );

				TestTrue( TEXT("AddSource result == true"), bResult);
				TestEqual( TEXT("ManifestCount == 2"), CountManifestEntries(TestManifest), 2 );

				// We should be able to find two unique entries by source
				TSharedPtr< FManifestEntry > FoundEntry1 = TestManifest.FindEntryBySource( TestNamespace, ConflictingSourceA );
				TestValid( TEXT("FoundEntry1 is valid"), FoundEntry1);

				TSharedPtr< FManifestEntry > FoundEntry2 = TestManifest.FindEntryBySource( TestNamespace, ConflictingSourceB );
				TestValid( TEXT("FoundEntry2 is valid"), FoundEntry2);

				TestTrue( TEXT("FoundEntry1 != FoundEntry2"), FoundEntry1 != FoundEntry2 );

				// We should be able to find two unique entries by context
				TSharedPtr< FManifestEntry > FoundEntry3 = TestManifest.FindEntryByContext( TestNamespace, ContextA );
				TestValid( TEXT("FoundEntry3 is valid"), FoundEntry3);

				TSharedPtr< FManifestEntry > FoundEntry4 = TestManifest.FindEntryByContext( TestNamespace, ContextB );
				TestValid( TEXT("FoundEntry3 is valid"), FoundEntry4);

				TestTrue( TEXT("FoundEntry3 != FoundEntry4"), FoundEntry3 != FoundEntry4 );

				// Found entry looked up by source A should match entry looked up by context A
				TestTrue( TEXT("FoundEntry1 == FoundEntry3"), FoundEntry1 == FoundEntry3 );

				// Found entry looked up by source B should match entry looked up by context B
				TestTrue( TEXT("FoundEntry2 == FoundEntry4"), FoundEntry2 == FoundEntry4 );

			}

			// Source mismatched by standard metadata type (not * prefixed)
			{
				FInternationalizationManifest TestManifest;

				FLocItem ConflictingSourceMetadataTypeA = Source;
				FLocItem ConflictingSourceMetadataTypeB = Source;

				// Set metadata with the same name but different type
				ConflictingSourceMetadataTypeA.MetadataObj->SetBoolField( TEXT("ConflictingType"), true );
				ConflictingSourceMetadataTypeB.MetadataObj->SetStringField( TEXT("ConflictingType"), TEXT("true") );

				TestManifest.AddSource( TestNamespace, ConflictingSourceMetadataTypeA, ContextA );
				bool bResult = TestManifest.AddSource( TestNamespace, ConflictingSourceMetadataTypeB, ContextB );

				TestTrue( TEXT("AddSource result == true"), bResult);
				TestEqual( TEXT("ManifestCount == 2"), CountManifestEntries(TestManifest), 2 );

				// We should be able to find two unique entries by source
				TSharedPtr< FManifestEntry > FoundEntry1 = TestManifest.FindEntryBySource( TestNamespace, ConflictingSourceMetadataTypeA );
				TestValid( TEXT("FoundEntry1 is valid"), FoundEntry1);

				TSharedPtr< FManifestEntry > FoundEntry2 = TestManifest.FindEntryBySource( TestNamespace, ConflictingSourceMetadataTypeB );
				TestValid( TEXT("FoundEntry2 is valid"), FoundEntry2);

				TestTrue( TEXT("FoundEntry1 != FoundEntry2"), FoundEntry1 != FoundEntry2 );

				// We should be able to find two unique entries by context
				TSharedPtr< FManifestEntry > FoundEntry3 = TestManifest.FindEntryByContext( TestNamespace, ContextA );
				TestValid( TEXT("FoundEntry3 is valid"), FoundEntry3);

				TSharedPtr< FManifestEntry > FoundEntry4 = TestManifest.FindEntryByContext( TestNamespace, ContextB );
				TestValid( TEXT("FoundEntry3 is valid"), FoundEntry4);

				TestTrue( TEXT("FoundEntry3 != FoundEntry4"), FoundEntry3 != FoundEntry4 );

				// Found entry looked up by source A should match entry looked up by context A
				TestTrue( TEXT("FoundEntry1 == FoundEntry3"), FoundEntry1 == FoundEntry3 );

				// Found entry looked up by source B should match entry looked up by context B
				TestTrue( TEXT("FoundEntry2 == FoundEntry4"), FoundEntry2 == FoundEntry4 );

			}

			// Source mismatched by standard metadata value (not * prefixed)
			{
				FInternationalizationManifest TestManifest;

				FLocItem ConflictingSourceMetadataValueA = Source;
				FLocItem ConflictingSourceMetadataValueB = Source;

				// Set metadata with the same name and type but different value
				ConflictingSourceMetadataValueA.MetadataObj->SetStringField( TEXT("ConflictingValue"), TEXT("A") );
				ConflictingSourceMetadataValueB.MetadataObj->SetStringField( TEXT("ConflictingValue"), TEXT("B") );

				TestManifest.AddSource( TestNamespace, ConflictingSourceMetadataValueA, ContextA );
				bool bResult = TestManifest.AddSource( TestNamespace, ConflictingSourceMetadataValueB, ContextB );

				TestTrue( TEXT("AddSource result == true"), bResult);
				TestEqual( TEXT("ManifestCount == 2"), CountManifestEntries(TestManifest), 2 );

				// We should be able to find two unique entries by source
				TSharedPtr< FManifestEntry > FoundEntry1 = TestManifest.FindEntryBySource( TestNamespace, ConflictingSourceMetadataValueA );
				TestValid( TEXT("FoundEntry1 is valid"), FoundEntry1);

				TSharedPtr< FManifestEntry > FoundEntry2 = TestManifest.FindEntryBySource( TestNamespace, ConflictingSourceMetadataValueB );
				TestValid( TEXT("FoundEntry2 is valid"), FoundEntry2);

				TestTrue( TEXT("FoundEntry1 != FoundEntry2"), FoundEntry1 != FoundEntry2 );

				// We should be able to find two unique entries by context
				TSharedPtr< FManifestEntry > FoundEntry3 = TestManifest.FindEntryByContext( TestNamespace, ContextA );
				TestValid( TEXT("FoundEntry3 is valid"), FoundEntry3);

				TSharedPtr< FManifestEntry > FoundEntry4 = TestManifest.FindEntryByContext( TestNamespace, ContextB );
				TestValid( TEXT("FoundEntry3 is valid"), FoundEntry4);

				TestTrue( TEXT("FoundEntry3 != FoundEntry4"), FoundEntry3 != FoundEntry4 );

				// Found entry looked up by source A should match entry looked up by context A
				TestTrue( TEXT("FoundEntry1 == FoundEntry3"), FoundEntry1 == FoundEntry3 );

				// Found entry looked up by source B should match entry looked up by context B
				TestTrue( TEXT("FoundEntry2 == FoundEntry4"), FoundEntry2 == FoundEntry4 );

			}

			// Source mismatched by * prefixed metadata type
			{
				FInternationalizationManifest TestManifest;

				FLocItem ConflictingSourceMetadataTypeA = Source;
				FLocItem ConflictingSourceMetadataTypeB = Source;

				// Set metadata with the same name but different type
				ConflictingSourceMetadataTypeA.MetadataObj->SetBoolField( TEXT("*ConflictingType"), true );
				ConflictingSourceMetadataTypeB.MetadataObj->SetStringField( TEXT("*ConflictingType"), TEXT("true") );

				TestManifest.AddSource( TestNamespace, ConflictingSourceMetadataTypeA, ContextA );

				// Though the Source items are considered to be a match(they are equal) in this case, the manifest reports this as a conflict
				//  and should not add an entry.  The reason is that AddSource does an 'exact' match check on the metadata object
				bool bResult = TestManifest.AddSource( TestNamespace, ConflictingSourceMetadataTypeB, ContextB );

				TestFalse( TEXT("AddSource result == false"), bResult);
				TestEqual( TEXT("ManifestCount == 1"), CountManifestEntries(TestManifest), 1 );

				// We should be able to find the entry using either Source FLocItem
				TSharedPtr< FManifestEntry > FoundEntry1 = TestManifest.FindEntryBySource( TestNamespace, ConflictingSourceMetadataTypeA );
				TestValid( TEXT("FoundEntry1 is valid"), FoundEntry1);

				TSharedPtr< FManifestEntry > FoundEntry2 = TestManifest.FindEntryBySource( TestNamespace, ConflictingSourceMetadataTypeB );
				TestValid( TEXT("FoundEntry2 is valid"), FoundEntry2);
			}

			// Source mismatched by * prefixed metadata value
			{
				FInternationalizationManifest TestManifest;

				FLocItem ConflictingSourceMetadataValueA = Source;
				FLocItem ConflictingSourceMetadataValueB = Source;

				// Set metadata with the same name and type but different value
				ConflictingSourceMetadataValueA.MetadataObj->SetStringField( TEXT("*ConflictingValue"), TEXT("A") );
				ConflictingSourceMetadataValueB.MetadataObj->SetStringField( TEXT("*ConflictingValue"), TEXT("B") );

				TestManifest.AddSource( TestNamespace, ConflictingSourceMetadataValueA, ContextA );

				// Thought the Source items are considered to be a match(they are equal) in this case, the manifest reports this as a conflict
				//  and should not add an entry.  The reason is that AddSource does an 'exact' match check on the metadata object
				bool bResult = TestManifest.AddSource( TestNamespace, ConflictingSourceMetadataValueB, ContextB );

				TestFalse( TEXT("AddSource result == false"), bResult);
				TestEqual( TEXT("ManifestCount == 1"), CountManifestEntries(TestManifest), 1 );

				// We should be able to find the entry using either Source FLocItem
				TSharedPtr< FManifestEntry > FoundEntry1 = TestManifest.FindEntryBySource( TestNamespace, ConflictingSourceMetadataValueA );
				TestValid( TEXT("FoundEntry1 is valid"), FoundEntry1);

				TSharedPtr< FManifestEntry > FoundEntry2 = TestManifest.FindEntryBySource( TestNamespace, ConflictingSourceMetadataValueB );
				TestValid( TEXT("FoundEntry2 is valid"), FoundEntry2);

			}

		}

		// Adding an entry that only differs in the optional flag 
		{
			FInternationalizationManifest TestManifest;

			// Reports success and our entry count does not change.  bIsOptional is not a key and is not used during lookup.  When
			//  we AddSource, we find an existing matching entry so AddSource returns true but no new entry is added.  The original
			//  entry's bIsOptional value is not updated.
			FContext ContextConflictingOptionalFlag = ContextA;
			ContextConflictingOptionalFlag.bIsOptional = !ContextA.bIsOptional;

			TestManifest.AddSource( TestNamespace, Source, ContextA );
			bool bResult = TestManifest.AddSource( TestNamespace, Source, ContextConflictingOptionalFlag);

			TestTrue( TEXT("AddSource result == true"), bResult);
			TestEqual( TEXT("ManifestCount == 1"), CountManifestEntries(TestManifest), 1 );

			// We should be able to look up the existing entry using the ContextConflictingOptionalFlag context but the entries bIsOptional flag will match ContextA
			TSharedPtr< FManifestEntry > FoundEntry = TestManifest.FindEntryByContext( TestNamespace, ContextConflictingOptionalFlag );
			if( !FoundEntry.IsValid() )
			{
				AddError(TEXT("FManifestEntry could not find entry using FindEntryByContext."));
			}
			else
			{
				TestTrue( TEXT("FoundEntry->bIsOptional == ContextA->bIsOptional"), FoundEntry->Contexts[0].bIsOptional == ContextA.bIsOptional );
			}
		}

		// Add an entry with null key metadata to see if we can retrieve it with non-null but empty key metadata
		{
			FInternationalizationManifest TestManifest;

			FContext ContextC;
			ContextC.Key			= TEXT("KeyC");
			ContextC.SourceLocation = TEXT("SourceLocationC");
			ContextC.InfoMetadataObj = MakeShareable( new FLocMetadataObject(*InfoMetadataB) );
			ContextC.KeyMetadataObj = NULL;

			Source.MetadataObj = NULL;
			TestManifest.AddSource( TestNamespace, Source, ContextC );

			//  Now give our context and source valid but empty metadata
			ContextC.KeyMetadataObj = MakeShareable( new FLocMetadataObject() );
			Source.MetadataObj = MakeShareable( new FLocMetadataObject() );

			// Ensure we find the entry we added by source
			TSharedPtr< FManifestEntry > FoundEntry;
			FoundEntry = TestManifest.FindEntryBySource( TestNamespace, Source );
			if( !FoundEntry.IsValid() )
			{
				AddError(TEXT("FManifestEntry could not find entry using FindEntryBySource."));
			}
			else
			{
				TestTrue( TEXT("FoundEntry->Source == Source"), FoundEntry->Source == Source );
			}

			// Ensure we find the entry we added by context
			FoundEntry = TestManifest.FindEntryByContext( TestNamespace, ContextC );
			if( !FoundEntry.IsValid() )
			{
				AddError(TEXT("FManifestEntry could not find entry using FindEntryByContext."));
			}
			else
			{
				TestTrue( TEXT("FoundEntry->Source == Source"), FoundEntry->Source == Source );
			}
		}

		// Add an entry with non-null but empty key metadata and see if we can retrieve null metadata
		{
			FInternationalizationManifest TestManifest;

			FContext ContextC;
			ContextC.Key			= TEXT("KeyC");
			ContextC.SourceLocation = TEXT("SourceLocationC");
			ContextC.InfoMetadataObj = MakeShareable( new FLocMetadataObject(*InfoMetadataB) );
			ContextC.KeyMetadataObj = MakeShareable( new FLocMetadataObject());

			Source.MetadataObj = MakeShareable( new FLocMetadataObject());
			TestManifest.AddSource( TestNamespace, Source, ContextC );

			//  Now give our context and source Null metadata
			ContextC.KeyMetadataObj = NULL;
			Source.MetadataObj = NULL;

			// Ensure we find the entry we added by source
			TSharedPtr< FManifestEntry > FoundEntry;
			FoundEntry = TestManifest.FindEntryBySource( TestNamespace, Source );
			if( !FoundEntry.IsValid() )
			{
				AddError(TEXT("FManifestEntry could not find entry using FindEntryBySource."));
			}
			else
			{
				TestTrue( TEXT("FoundEntry->Source == Source"), FoundEntry->Source == Source );
			}

			// Ensure we find the entry we added by context
			FoundEntry = TestManifest.FindEntryByContext( TestNamespace, ContextC );
			if( !FoundEntry.IsValid() )
			{
				AddError(TEXT("FManifestEntry could not find entry using FindEntryByContext."));
			}
			else
			{
				TestTrue( TEXT("FoundEntry->Source == Source"), FoundEntry->Source == Source );
			}
		}
	}

	return true;
}
예제 #20
0
bool FRangeBoundTest::RunTest( const FString& Parameters )
{
	// ensure template instantiation works
	FDateRange DateRange;
	FDoubleRange DoubleRange;
	FFloatRange FloatRange;
	FInt8Range Int8Range;
	FInt16Range Int16Range;
	FInt32Range Int32Range;
	FInt64Range Int64Range;

	// bound types must be correct after construction
	FFloatRangeBound b1_1 = FFloatRangeBound::Exclusive(2.0f);
	FFloatRangeBound b1_2 = FFloatRangeBound::Inclusive(2.0f);
	FFloatRangeBound b1_3 = FFloatRangeBound::Open();
	FFloatRangeBound b1_4 = 2;

	TestTrue(TEXT("Exclusive bound constructor must create exclusive bound"), b1_1.IsExclusive());
	TestTrue(TEXT("Exclusive bound constructor must create closed bound"), b1_1.IsClosed());
	TestFalse(TEXT("Exclusive bound constructor must not create inclusive bound"), b1_1.IsInclusive());
	TestFalse(TEXT("Exclusive bound constructor must not create open bound"), b1_1.IsOpen());
	TestEqual(TEXT("Exclusive bound constructor must create the correct value"), b1_1.GetValue(), 2.0f);

	TestTrue(TEXT("Inclusive bound constructor must create exclusive bound"), b1_2.IsInclusive());
	TestTrue(TEXT("Inclusive bound constructor must create closed bound"), b1_2.IsClosed());
	TestFalse(TEXT("Inclusive bound constructor must not create exclusive bound"), b1_2.IsExclusive());
	TestFalse(TEXT("Inclusive bound constructor must not create open bound"), b1_2.IsOpen());
	TestEqual(TEXT("Inclusive bound constructor must create the correct value"), b1_2.GetValue(), 2.0f);

	TestTrue(TEXT("Open bound constructor must create open bound"), b1_3.IsOpen());
	TestFalse(TEXT("Open bound constructor must not create closed bound"), b1_3.IsClosed());
	TestFalse(TEXT("Open bound constructor must not create exclusive bound"), b1_3.IsExclusive());
	TestFalse(TEXT("Open bound constructor must not create inclusive bound"), b1_3.IsInclusive());

	TestTrue(TEXT("Implicit constructor must create an inclusive bound"), b1_4.IsInclusive());
	TestEqual(TEXT("Implicit constructor must create the correct value"), b1_4, b1_2);

	// comparisons must be correct
	FFloatRangeBound b2_1 = FFloatRangeBound::Exclusive(2.0f);
	FFloatRangeBound b2_2 = FFloatRangeBound::Exclusive(2.0f);
	FFloatRangeBound b2_3 = FFloatRangeBound::Inclusive(2.0f);
	FFloatRangeBound b2_4 = FFloatRangeBound::Inclusive(2.0f);
	FFloatRangeBound b2_5 = FFloatRangeBound::Open();
	FFloatRangeBound b2_6 = FFloatRangeBound::Open();

	TestTrue(TEXT("Equal exclusive bounds must be equal"), b2_1 == b2_2);
	TestTrue(TEXT("Equal inclusive bounds must be equal"), b2_3 == b2_4);
	TestTrue(TEXT("Open bounds must be equal"), b2_5 == b2_6);

	TestFalse(TEXT("Equal exclusive bounds must not be unequal"), b2_1 != b2_2);
	TestFalse(TEXT("Equal inclusive bounds must not be unequal"), b2_3 != b2_4);
	TestFalse(TEXT("Open bounds must not be unequal"), b2_5 != b2_6);

	FFloatRangeBound b2_7 = FFloatRangeBound::Exclusive(3.0f);
	FFloatRangeBound b2_8 = FFloatRangeBound::Inclusive(3.0f);

	TestTrue(TEXT("Unequal exclusive bounds must be unequal"), b2_1 != b2_7);
	TestTrue(TEXT("Unequal inclusive bounds must be unequal"), b2_2 != b2_8);

	TestFalse(TEXT("Unequal exclusive bounds must not be equal"), b2_1 == b2_7);
	TestFalse(TEXT("Unequal inclusive bounds must not be equal"), b2_2 == b2_8);

	// min-max comparisons between bounds must be correct
	FFloatRangeBound b3_1 = FFloatRangeBound::Exclusive(2.0f);
	FFloatRangeBound b3_2 = FFloatRangeBound::Inclusive(2.0f);
	FFloatRangeBound b3_3 = FFloatRangeBound::Open();

	TestEqual(TEXT("'[2' must be less than '(2' <1>"), FFloatRangeBound::MinLower(b3_2, b3_1), b3_2);
	TestEqual(TEXT("'[2' must be less than '(2' <2>"), FFloatRangeBound::MinLower(b3_1, b3_2), b3_2);
	TestEqual(TEXT("Open lower bound must be less than '(2' <1>"), FFloatRangeBound::MinLower(b3_3, b3_1), b3_3);
	TestEqual(TEXT("Open lower bound must be less than '(2' <2>"), FFloatRangeBound::MinLower(b3_1, b3_3), b3_3);
	TestEqual(TEXT("Open lower bound must be less than '[2' <1>"), FFloatRangeBound::MinLower(b3_3, b3_2), b3_3);
	TestEqual(TEXT("Open lower bound must be less than '[2' <2>"), FFloatRangeBound::MinLower(b3_2, b3_3), b3_3);

	TestEqual(TEXT("'(2' must be greater than '[2' <1>"), FFloatRangeBound::MaxLower(b3_2, b3_1), b3_1);
	TestEqual(TEXT("'(2' must be greater than '[2' <2>"), FFloatRangeBound::MaxLower(b3_1, b3_2), b3_1);
	TestEqual(TEXT("'(2' must be greater than open lower bound <1>"), FFloatRangeBound::MaxLower(b3_3, b3_1), b3_1);
	TestEqual(TEXT("'(2' must be greater than open lower bound <2>"), FFloatRangeBound::MaxLower(b3_1, b3_3), b3_1);
	TestEqual(TEXT("'[2' must be greater than open lower bound <1>"), FFloatRangeBound::MaxLower(b3_3, b3_2), b3_2);
	TestEqual(TEXT("'[2' must be greater than open lower bound <2>"), FFloatRangeBound::MaxLower(b3_2, b3_3), b3_2);

	TestEqual(TEXT("'2)' must be less than '2]' <1>"), FFloatRangeBound::MinUpper(b3_2, b3_1), b3_1);
	TestEqual(TEXT("'2)' must be less than '2]' <2>"), FFloatRangeBound::MinUpper(b3_1, b3_2), b3_1);
	TestEqual(TEXT("'2)' must be less than open upper bound <1>"), FFloatRangeBound::MinUpper(b3_3, b3_1), b3_1);
	TestEqual(TEXT("'2)' must be less than open upper bound <2>"), FFloatRangeBound::MinUpper(b3_1, b3_3), b3_1);
	TestEqual(TEXT("'2]' must be less than open upper bound <1>"), FFloatRangeBound::MinUpper(b3_3, b3_2), b3_2);
	TestEqual(TEXT("'2]' must be less than open upper bound"), FFloatRangeBound::MinUpper(b3_2, b3_3), b3_2);

	TestEqual(TEXT("'2]' must be greater than '2)' <1>"), FFloatRangeBound::MaxUpper(b3_2, b3_1), b3_2);
	TestEqual(TEXT("'2]' must be greater than '2)' <2>"), FFloatRangeBound::MaxUpper(b3_1, b3_2), b3_2);
	TestEqual(TEXT("Open upper bound must be greater than '2)' <1>"), FFloatRangeBound::MaxUpper(b3_3, b3_1), b3_3);
	TestEqual(TEXT("Open upper bound must be greater than '2)' <2>"), FFloatRangeBound::MaxUpper(b3_1, b3_3), b3_3);
	TestEqual(TEXT("Open upper bound must be greater than '2]' <1>"), FFloatRangeBound::MaxUpper(b3_3, b3_2), b3_3);
	TestEqual(TEXT("Open upper bound must be greater than '2]' <2>"), FFloatRangeBound::MaxUpper(b3_2, b3_3), b3_3);

	FFloatRangeBound b4_1 = FFloatRangeBound::Exclusive(3);
	FFloatRangeBound b4_2 = FFloatRangeBound::Inclusive(3);

	TestEqual(TEXT("'(2' must be less than '[3' <1>"), FFloatRangeBound::MinLower(b3_1, b4_2), b3_1);
	TestEqual(TEXT("'(2' must be less than '[3' <2>"), FFloatRangeBound::MinLower(b4_2, b3_1), b3_1);
	TestEqual(TEXT("'[2' must be less than '[3' <1>"), FFloatRangeBound::MinLower(b3_2, b4_2), b3_2);
	TestEqual(TEXT("'[2' must be less than '[3' <2>"), FFloatRangeBound::MinLower(b4_2, b3_2), b3_2);

	TestEqual(TEXT("'[3' must be greater than '(2' <1>"), FFloatRangeBound::MaxLower(b3_1, b4_2), b4_2);
	TestEqual(TEXT("'[3' must be greater than '(2' <2>"), FFloatRangeBound::MaxLower(b4_2, b3_1), b4_2);
	TestEqual(TEXT("'[3' must be greater than '[2' <1>"), FFloatRangeBound::MaxLower(b3_2, b4_2), b4_2);
	TestEqual(TEXT("'[3' must be greater than '[2' <2>"), FFloatRangeBound::MaxLower(b4_2, b3_2), b4_2);

	return true;
}
void MockOLED::drawSetupMock(MockOLED& obj) {
	Serial.begin (9600); //alternately comment out if using more than one setup function
	TestTrue ("OLED init test", obj.exists);
	int printed = obj.MockPrintToOLED ("Setting Up"); //There's an interior method here that interacts with the OLED
	TestEqual ("drawSetup Print Check", printed, 1 );
}