diff --git a/ReflexToQ3/test/catch-entityconverter.cpp b/ReflexToQ3/test/catch-entityconverter.cpp new file mode 100644 index 0000000..778bce8 --- /dev/null +++ b/ReflexToQ3/test/catch-entityconverter.cpp @@ -0,0 +1,510 @@ +/* + * ===================================================================================== + * + * Filename: catch-entityconverter.cpp + * + * Description: Unit tests for EntityConverter class + * + * Version: 0.1 + * Created: 07/14/2017 20:36:31 PM + * Revision: none + * Compiler: gcc + * + * Author: suhrke@teknik.io + * + * ===================================================================================== + */ +#include +#include +#include +#include + +#include "EntityConverter.hpp" + +#define PICKUP_FILENAME "ReflexToQ3/r2x.pck" +#define DELTA 0.00001 + + + +TEST_CASE( "r2x: Unsupported entity types cause return of empty vector", "[EntityConverter]" ) { + + // Instantiate object + EntityConverter ec (PICKUP_FILENAME); + + // Mock up entity + std::vector entity; + entity.push_back(" type NotAType"); + + // Mock up entity queue + std::queue> q; + q.push( entity ); + + // Match related entities (none) + ec.extractMapInfo( q ); + + // Convert a single entity + std::vector converted = ec.convert(entity); + + REQUIRE( converted.size() == 0 ); +} + + + +TEST_CASE( "r2x: a single Pickup entity can be converted", "[EntityConverter]" ) { + + // Instantiate object + EntityConverter ec (PICKUP_FILENAME); + + // Mock up entity + std::vector entity; + entity.push_back(" type Pickup"); + entity.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); + entity.push_back(" Vector3 angles 180.00000 0.00000 0.00000"); + entity.push_back(" UInt8 pickupType 2"); + + // Mock up entity queue + std::queue> q; + q.push( entity ); + + // Match related entities (none) + ec.extractMapInfo( q ); + + // Convert a single entity + std::vector converted = ec.convert(entity); + + REQUIRE( converted[0] == "\"classname\" \"weapon_grenadelauncher\"\n" ); + + // The z (vertical) is offset by +2 + std::istringstream iss(converted[1]); + std::string attribute; + std::string coords[2]; + float offsetCoord; + iss >> attribute >> coords[0] >> coords[1] >> offsetCoord; + + REQUIRE( attribute == "\"origin\"" ); + REQUIRE( coords[0] == "\"-216.00000" ); + REQUIRE( coords[1] == "-1488.000488" ); + REQUIRE( fabs(-130.00000 - offsetCoord) <= DELTA ); +} + + + +TEST_CASE( "r2x: a single PlayerSpawn (race) entity can be converted", "[EntityConverter]" ) { + + // Instantiate object + EntityConverter ec (PICKUP_FILENAME); + + // Mock up WorldSpawn entity + // (needed for mode info) + std::vector worldspawn; + worldspawn.push_back(" type WorldSpawn"); + worldspawn.push_back(" Bool8 modeCTF 0"); + worldspawn.push_back(" Bool8 modeFFA 0"); + worldspawn.push_back(" Bool8 modeTDM 0"); + worldspawn.push_back(" Bool8 mode1v1 0"); + + + // Mock up entity + std::vector entity; + entity.push_back(" type PlayerSpawn"); + entity.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); + entity.push_back(" Vector3 angles 180.00000 0.00000 0.00000"); + entity.push_back(" Bool8 teamA 0"); + entity.push_back(" Bool8 teamB 0"); + entity.push_back(" Bool8 modeCTF 0"); + entity.push_back(" Bool8 modeFFA 0"); + entity.push_back(" Bool8 modeTDM 0"); + entity.push_back(" Bool8 mode1v1 0"); + + // Mock up entity queue + std::queue> q; + q.push( worldspawn ); + q.push( entity ); + + // Match related entities (none) + ec.extractMapInfo( q ); + + // Convert a single entity (worldspawn conversion returns empty vector + // BUT sets the supported game modes for entities in that worldspawn + std::vector unused = ec.convert(worldspawn); + std::vector converted = ec.convert(entity); + + REQUIRE( converted[0] == "\"classname\" \"info_player_race\"\n" ); + REQUIRE( converted[1] == "\"target\" \"cp1\"\n" ); + REQUIRE( converted[2] == "\"race_place\" \"-1\"\n" ); + + // The z (vertical) is offset by +32 + std::istringstream iss(converted[3]); + std::string attribute; + std::string coords[2]; + float offsetCoord; + iss >> attribute >> coords[0] >> coords[1] >> offsetCoord; + + REQUIRE( attribute == "\"origin\"" ); + REQUIRE( coords[0] == "\"-216.00000" ); + REQUIRE( coords[1] == "-1488.000488" ); + REQUIRE( fabs(-100.00000 - offsetCoord) <= DELTA ); + + SECTION( "Converted angles are valid (Different coordinate system handedness)" ) { + std::istringstream angleLineStream(converted[4]); + std::string angleAttribute; + std::string a; + float angle; + angleLineStream >> attribute >> a; + a.erase(a.begin()); //removing preceding quote is necessary + + std::stringstream angleStream(a); + angleStream >> angle; + + REQUIRE( attribute == "\"angle\"" ); + REQUIRE( fabs( -90.0 - angle) <= DELTA ); + } + + + SECTION( "Encountering a new worldspawn reenables all modes" ) { + std::vector basicWorldspawn; + basicWorldspawn.push_back(" type WorldSpawn"); + + std::vector e; + e.push_back(" type PlayerSpawn"); + e.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); + e.push_back(" Vector3 angles 180.00000 0.00000 0.00000"); + + std::vector u = ec.convert(basicWorldspawn); + std::vector c = ec.convert(e); + REQUIRE( c[0] == "\"classname\" \"info_player_deathmatch\"\n" ); + } +} + + + + +TEST_CASE( "r2x: a single PlayerSpawn (teamA) entity can be converted", "[EntityConverter]" ) { + + // Instantiate object + EntityConverter ec (PICKUP_FILENAME); + + // Mock up entity + std::vector entity; + entity.push_back(" type PlayerSpawn"); + entity.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); + entity.push_back(" Vector3 angles 180.00000 0.00000 0.00000"); + entity.push_back(" Bool8 teamB 0"); + entity.push_back(" Bool8 modeRace 0"); + + // Mock up entity queue + std::queue> q; + q.push( entity ); + + // Match related entities (none) + ec.extractMapInfo( q ); + + // Convert a single entity + std::vector converted = ec.convert(entity); + + REQUIRE( converted[0] == "\"classname\" \"info_player_team1\"\n" ); + + // The z (vertical) is offset by +32 + std::istringstream iss(converted[1]); + std::string attribute; + std::string coords[2]; + float offsetCoord; + iss >> attribute >> coords[0] >> coords[1] >> offsetCoord; + + REQUIRE( attribute == "\"origin\"" ); + REQUIRE( coords[0] == "\"-216.00000" ); + REQUIRE( coords[1] == "-1488.000488" ); + REQUIRE( fabs(-100.00000 - offsetCoord) <= DELTA ); +} + + + +TEST_CASE( "r2x: a single PlayerSpawn (non-team) entity can be converted", "[EntityConverter]" ) { + + // Instantiate object + EntityConverter ec (PICKUP_FILENAME); + + // Mock up entity + std::vector entity; + entity.push_back(" type PlayerSpawn"); + entity.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); + entity.push_back(" Vector3 angles 180.00000 0.00000 0.00000"); + + // Mock up entity queue + std::queue> q; + q.push( entity ); + + // Match related entities (none) + ec.extractMapInfo( q ); + + // Convert a single entity + std::vector converted = ec.convert(entity); + + REQUIRE( converted[0] == "\"classname\" \"info_player_deathmatch\"\n" ); + + // The z (vertical) is offset by +32 + std::istringstream iss(converted[1]); + std::string attribute; + std::string coords[2]; + float offsetCoord; + iss >> attribute >> coords[0] >> coords[1] >> offsetCoord; + + REQUIRE( attribute == "\"origin\"" ); + REQUIRE( coords[0] == "\"-216.00000" ); + REQUIRE( coords[1] == "-1488.000488" ); + REQUIRE( fabs(-100.00000 - offsetCoord) <= DELTA ); +} + + + + +TEST_CASE( "r2x: a single RaceStart entity can be converted", "[EntityConverter]" ) { + + // Instantiate object + EntityConverter ec (PICKUP_FILENAME); + + // Mock up entity + std::vector entity; + entity.push_back(" type RaceStart"); + + // Mock up entity queue + std::queue> q; + q.push( entity ); + + // Match related entities (none) + ec.extractMapInfo( q ); + + // Convert a single entity + std::vector converted = ec.convert(entity); + + REQUIRE( converted[0] == "\"classname\" \"trigger_race_checkpoint\"\n" ); + REQUIRE( converted[1] == "\"targetname\" \"cp1\"\n" ); + REQUIRE( converted[2] == "\"cnt\" \"1\"\n" ); +} + + + +TEST_CASE( "r2x: a single RaceFinish entity can be converted", "[EntityConverter]" ) { + + // Instantiate object + EntityConverter ec (PICKUP_FILENAME); + + // Mock up entity + std::vector entity; + entity.push_back(" type RaceFinish"); + + // Mock up entity queue + std::queue> q; + q.push( entity ); + + // Match related entities (none) + ec.extractMapInfo( q ); + + // Convert a single entity + std::vector converted = ec.convert(entity); + + REQUIRE( converted[0] == "\"classname\" \"trigger_race_checkpoint\"\n" ); + REQUIRE( converted[1] == "\"targetname\" \"finish\"\n" ); + REQUIRE( converted[2] == "\"cnt\" \"0\"\n" ); +} + + + +TEST_CASE( "r2x: a single Teleporter and related Target can be converted", "[EntityConverter]" ) { + + // Instantiate object + EntityConverter ec (PICKUP_FILENAME); + + // Mock up Teleporter entity + std::vector entity; + entity.push_back(" type Teleporter"); + entity.push_back(" String32 target tp1"); + + // Mock up Target entity + std::vector entity2; + entity2.push_back(" type Target"); + entity2.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); + entity2.push_back(" String32 name tp1"); + + // Mock up entity queue + std::queue> q; + q.push( entity ); + q.push( entity2 ); + + // Match related entities (one pair) + ec.extractMapInfo( q ); + + // Convert two entities + std::vector converted = ec.convert(entity); + REQUIRE( converted[0] == "\"classname\" \"trigger_teleport\"\n" ); + REQUIRE( converted[1] == "\"target\" \"tp1\"\n" ); + + std::vector converted2 = ec.convert(entity2); + REQUIRE( converted2[0] == "\"classname\" \"misc_teleporter_dest\"\n" ); + REQUIRE( converted2[2] == "\"targetname\" \"tp1\"\n" ); + // + // The z (vertical) is offset by +32 + std::istringstream iss(converted2[1]); + std::string attribute; + std::string coords[2]; + float offsetCoord; + iss >> attribute >> coords[0] >> coords[1] >> offsetCoord; + + // next REQUIRE fails without busy wait + for( int i = 0; i < 10000000; i++ ) + int x = i; + + REQUIRE( attribute == "\"origin\"" ); + REQUIRE( coords[0] == "\"-216.00000" ); + REQUIRE( coords[1] == "-1488.000488" ); + REQUIRE( fabs(-100.00000 - offsetCoord) <= DELTA ); + + SECTION( "When angle unspecified, defaults to 0.0 (converted to 90.0)" ) { + std::istringstream angleStream(converted2[3]); + std::string a; + float angle; + angleStream >> attribute >> a; + a.erase(a.begin()); //removing preceding quote is necessary + std::stringstream out(a); + out >> angle; + REQUIRE( fabs(90.0 - angle) <= DELTA ); + } +} + + + +TEST_CASE( "r2x: a single JumpPad and related Target can be converted", "[EntityConverter]" ) { + + // Instantiate object + EntityConverter ec (PICKUP_FILENAME); + + // Mock up JumpPad entity + std::vector entity; + entity.push_back(" type JumpPad"); + entity.push_back(" String32 target jp1"); + + // Mock up Target entity + std::vector entity2; + entity2.push_back(" type Target"); + entity2.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); + entity2.push_back(" String32 name jp1"); + + // Mock up entity queue + std::queue> q; + q.push( entity ); + q.push( entity2 ); + + // Match related entities (one pair) + ec.extractMapInfo( q ); + + // Convert two entities + std::vector converted = ec.convert(entity); + REQUIRE( converted[0] == "\"classname\" \"trigger_push\"\n" ); + REQUIRE( converted[1] == "\"target\" \"jp1\"\n" ); + + std::vector converted2 = ec.convert(entity2); + REQUIRE( converted2[0] == "\"classname\" \"target_position\"\n" ); + REQUIRE( converted2[1] == "\"origin\" \"-216.00000 -1488.000488 -132.00000\"\n" ); + REQUIRE( converted2[2] == "\"targetname\" \"jp1\"\n" ); +} + + + +TEST_CASE( "r2x: a single PointLight entity can be converted", "[EntityConverter]" ) { + + // Instantiate object + EntityConverter ec (PICKUP_FILENAME); + + // Mock up entity + std::vector entity; + entity.push_back(" type PointLight"); + entity.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); + entity.push_back(" ColourXRGB32 color ffffc400"); + entity.push_back(" Float intensity 1.500000"); + entity.push_back(" Float nearAttenuation 32.000000"); + entity.push_back(" Float farAttenuation 160.000000"); + + // Mock up entity queue + std::queue> q; + q.push( entity ); + + // Match related entities (none) + ec.extractMapInfo( q ); + + // Convert a single entity + std::vector converted = ec.convert(entity); + + REQUIRE( converted[0] == "\"classname\" \"light\"\n" ); + REQUIRE( converted[1] == "\"origin\" \"-216.00000 -1488.000488 -132.00000\"\n" ); + REQUIRE( converted[2] == "\"light\" \"75\"\n" ); + + INFO( converted[3] ); + std::istringstream iss(converted[3]); + std::string attribute; + std::string r; + float red; + float green; + float blue; + iss >> attribute >> r >> green >> blue; + r.erase(r.begin()); //removing preceding quote is necessary + std::stringstream redStream(r); + redStream >> red; + + REQUIRE( attribute == "\"_color\"" ); + + REQUIRE( fabs( 1.0 - red) <= DELTA ); + REQUIRE( fabs( 0.768627 - green) <= DELTA ); + REQUIRE( fabs( 0.0 - blue) <= DELTA ); +} + + +TEST_CASE( "r2x: PointLight defaults to white light of typical intensity", "[EntityConverter]" ) { + + // Instantiate object + EntityConverter ec (PICKUP_FILENAME); + + // Mock up entity + std::vector entity; + entity.push_back(" type PointLight"); + entity.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); + + // Mock up entity queue + std::queue> q; + q.push( entity ); + + // Match related entities (none) + ec.extractMapInfo( q ); + + // Convert a single entity + std::vector converted = ec.convert(entity); + + REQUIRE( converted[0] == "\"classname\" \"light\"\n" ); + REQUIRE( converted[1] == "\"origin\" \"-216.00000 -1488.000488 -132.00000\"\n" ); + REQUIRE( converted[2] == "\"light\" \"50\"\n" ); + + INFO( converted[3] ); + std::istringstream iss(converted[3]); + std::string attribute; + std::string r; + float red; + float green; + float blue; + iss >> attribute >> r >> green >> blue; + r.erase(r.begin()); //removing preceding quote is necessary + std::stringstream redStream(r); + redStream >> red; + + REQUIRE( attribute == "\"_color\"" ); + + REQUIRE( fabs( 0.0 - red) <= DELTA ); + REQUIRE( fabs( 0.0 - green) <= DELTA ); + REQUIRE( fabs( 0.0 - blue) <= DELTA ); + +} + + + + + + + diff --git a/ReflexToQ3/test/catch.cpp b/ReflexToQ3/test/catch.cpp index 36a2a22..1aa7ae8 100644 --- a/ReflexToQ3/test/catch.cpp +++ b/ReflexToQ3/test/catch.cpp @@ -19,499 +19,7 @@ #define CATCH_CONFIG_MAIN #include "catch.hpp" #include "catch-parser.cpp" -#include -#include -#include -#include - -#include "EntityConverter.hpp" - -#define PICKUP_FILENAME "ReflexToQ3/r2x.pck" -#define DELTA 0.00001 - - - -TEST_CASE( "r2x: Unsupported entity types cause return of empty vector", "[EntityConverter]" ) { - - // Instantiate object - EntityConverter ec (PICKUP_FILENAME); - - // Mock up entity - std::vector entity; - entity.push_back(" type NotAType"); - - // Mock up entity queue - std::queue> q; - q.push( entity ); - - // Match related entities (none) - ec.extractMapInfo( q ); - - // Convert a single entity - std::vector converted = ec.convert(entity); - - REQUIRE( converted.size() == 0 ); -} - - - -TEST_CASE( "r2x: a single Pickup entity can be converted", "[EntityConverter]" ) { - - // Instantiate object - EntityConverter ec (PICKUP_FILENAME); - - // Mock up entity - std::vector entity; - entity.push_back(" type Pickup"); - entity.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); - entity.push_back(" Vector3 angles 180.00000 0.00000 0.00000"); - entity.push_back(" UInt8 pickupType 2"); - - // Mock up entity queue - std::queue> q; - q.push( entity ); - - // Match related entities (none) - ec.extractMapInfo( q ); - - // Convert a single entity - std::vector converted = ec.convert(entity); - - REQUIRE( converted[0] == "\"classname\" \"weapon_grenadelauncher\"\n" ); - - // The z (vertical) is offset by +2 - std::istringstream iss(converted[1]); - std::string attribute; - std::string coords[2]; - float offsetCoord; - iss >> attribute >> coords[0] >> coords[1] >> offsetCoord; - - REQUIRE( attribute == "\"origin\"" ); - REQUIRE( coords[0] == "\"-216.00000" ); - REQUIRE( coords[1] == "-1488.000488" ); - REQUIRE( fabs(-130.00000 - offsetCoord) <= DELTA ); -} - - - -TEST_CASE( "r2x: a single PlayerSpawn (race) entity can be converted", "[EntityConverter]" ) { - - // Instantiate object - EntityConverter ec (PICKUP_FILENAME); - - // Mock up WorldSpawn entity - // (needed for mode info) - std::vector worldspawn; - worldspawn.push_back(" type WorldSpawn"); - worldspawn.push_back(" Bool8 modeCTF 0"); - worldspawn.push_back(" Bool8 modeFFA 0"); - worldspawn.push_back(" Bool8 modeTDM 0"); - worldspawn.push_back(" Bool8 mode1v1 0"); - - - // Mock up entity - std::vector entity; - entity.push_back(" type PlayerSpawn"); - entity.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); - entity.push_back(" Vector3 angles 180.00000 0.00000 0.00000"); - entity.push_back(" Bool8 teamA 0"); - entity.push_back(" Bool8 teamB 0"); - entity.push_back(" Bool8 modeCTF 0"); - entity.push_back(" Bool8 modeFFA 0"); - entity.push_back(" Bool8 modeTDM 0"); - entity.push_back(" Bool8 mode1v1 0"); - - // Mock up entity queue - std::queue> q; - q.push( worldspawn ); - q.push( entity ); - - // Match related entities (none) - ec.extractMapInfo( q ); - - // Convert a single entity (worldspawn conversion returns empty vector - // BUT sets the supported game modes for entities in that worldspawn - std::vector unused = ec.convert(worldspawn); - std::vector converted = ec.convert(entity); - - REQUIRE( converted[0] == "\"classname\" \"info_player_race\"\n" ); - REQUIRE( converted[1] == "\"target\" \"cp1\"\n" ); - REQUIRE( converted[2] == "\"race_place\" \"-1\"\n" ); - - // The z (vertical) is offset by +32 - std::istringstream iss(converted[3]); - std::string attribute; - std::string coords[2]; - float offsetCoord; - iss >> attribute >> coords[0] >> coords[1] >> offsetCoord; - - REQUIRE( attribute == "\"origin\"" ); - REQUIRE( coords[0] == "\"-216.00000" ); - REQUIRE( coords[1] == "-1488.000488" ); - REQUIRE( fabs(-100.00000 - offsetCoord) <= DELTA ); - - SECTION( "Converted angles are valid (Different coordinate system handedness)" ) { - std::istringstream angleLineStream(converted[4]); - std::string angleAttribute; - std::string a; - float angle; - angleLineStream >> attribute >> a; - a.erase(a.begin()); //removing preceding quote is necessary - - std::stringstream angleStream(a); - angleStream >> angle; - - REQUIRE( attribute == "\"angle\"" ); - REQUIRE( fabs( -90.0 - angle) <= DELTA ); - } - - - SECTION( "Encountering a new worldspawn reenables all modes" ) { - std::vector basicWorldspawn; - basicWorldspawn.push_back(" type WorldSpawn"); - - std::vector e; - e.push_back(" type PlayerSpawn"); - e.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); - e.push_back(" Vector3 angles 180.00000 0.00000 0.00000"); - - std::vector u = ec.convert(basicWorldspawn); - std::vector c = ec.convert(e); - REQUIRE( c[0] == "\"classname\" \"info_player_deathmatch\"\n" ); - } -} - - - - -TEST_CASE( "r2x: a single PlayerSpawn (teamA) entity can be converted", "[EntityConverter]" ) { - - // Instantiate object - EntityConverter ec (PICKUP_FILENAME); - - // Mock up entity - std::vector entity; - entity.push_back(" type PlayerSpawn"); - entity.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); - entity.push_back(" Vector3 angles 180.00000 0.00000 0.00000"); - entity.push_back(" Bool8 teamB 0"); - entity.push_back(" Bool8 modeRace 0"); - - // Mock up entity queue - std::queue> q; - q.push( entity ); - - // Match related entities (none) - ec.extractMapInfo( q ); - - // Convert a single entity - std::vector converted = ec.convert(entity); - - REQUIRE( converted[0] == "\"classname\" \"info_player_team1\"\n" ); - - // The z (vertical) is offset by +32 - std::istringstream iss(converted[1]); - std::string attribute; - std::string coords[2]; - float offsetCoord; - iss >> attribute >> coords[0] >> coords[1] >> offsetCoord; - - REQUIRE( attribute == "\"origin\"" ); - REQUIRE( coords[0] == "\"-216.00000" ); - REQUIRE( coords[1] == "-1488.000488" ); - REQUIRE( fabs(-100.00000 - offsetCoord) <= DELTA ); -} - - - -TEST_CASE( "r2x: a single PlayerSpawn (non-team) entity can be converted", "[EntityConverter]" ) { - - // Instantiate object - EntityConverter ec (PICKUP_FILENAME); - - // Mock up entity - std::vector entity; - entity.push_back(" type PlayerSpawn"); - entity.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); - entity.push_back(" Vector3 angles 180.00000 0.00000 0.00000"); - - // Mock up entity queue - std::queue> q; - q.push( entity ); - - // Match related entities (none) - ec.extractMapInfo( q ); - - // Convert a single entity - std::vector converted = ec.convert(entity); - - REQUIRE( converted[0] == "\"classname\" \"info_player_deathmatch\"\n" ); - - // The z (vertical) is offset by +32 - std::istringstream iss(converted[1]); - std::string attribute; - std::string coords[2]; - float offsetCoord; - iss >> attribute >> coords[0] >> coords[1] >> offsetCoord; - - REQUIRE( attribute == "\"origin\"" ); - REQUIRE( coords[0] == "\"-216.00000" ); - REQUIRE( coords[1] == "-1488.000488" ); - REQUIRE( fabs(-100.00000 - offsetCoord) <= DELTA ); -} - - - - -TEST_CASE( "r2x: a single RaceStart entity can be converted", "[EntityConverter]" ) { - - // Instantiate object - EntityConverter ec (PICKUP_FILENAME); - - // Mock up entity - std::vector entity; - entity.push_back(" type RaceStart"); - - // Mock up entity queue - std::queue> q; - q.push( entity ); - - // Match related entities (none) - ec.extractMapInfo( q ); - - // Convert a single entity - std::vector converted = ec.convert(entity); - - REQUIRE( converted[0] == "\"classname\" \"trigger_race_checkpoint\"\n" ); - REQUIRE( converted[1] == "\"targetname\" \"cp1\"\n" ); - REQUIRE( converted[2] == "\"cnt\" \"1\"\n" ); -} - - - -TEST_CASE( "r2x: a single RaceFinish entity can be converted", "[EntityConverter]" ) { - - // Instantiate object - EntityConverter ec (PICKUP_FILENAME); - - // Mock up entity - std::vector entity; - entity.push_back(" type RaceFinish"); - - // Mock up entity queue - std::queue> q; - q.push( entity ); - - // Match related entities (none) - ec.extractMapInfo( q ); - - // Convert a single entity - std::vector converted = ec.convert(entity); - - REQUIRE( converted[0] == "\"classname\" \"trigger_race_checkpoint\"\n" ); - REQUIRE( converted[1] == "\"targetname\" \"finish\"\n" ); - REQUIRE( converted[2] == "\"cnt\" \"0\"\n" ); -} - - - -TEST_CASE( "r2x: a single Teleporter and related Target can be converted", "[EntityConverter]" ) { - - // Instantiate object - EntityConverter ec (PICKUP_FILENAME); - - // Mock up Teleporter entity - std::vector entity; - entity.push_back(" type Teleporter"); - entity.push_back(" String32 target tp1"); - - // Mock up Target entity - std::vector entity2; - entity2.push_back(" type Target"); - entity2.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); - entity2.push_back(" String32 name tp1"); - - // Mock up entity queue - std::queue> q; - q.push( entity ); - q.push( entity2 ); - - // Match related entities (one pair) - ec.extractMapInfo( q ); - - // Convert two entities - std::vector converted = ec.convert(entity); - REQUIRE( converted[0] == "\"classname\" \"trigger_teleport\"\n" ); - REQUIRE( converted[1] == "\"target\" \"tp1\"\n" ); - - std::vector converted2 = ec.convert(entity2); - REQUIRE( converted2[0] == "\"classname\" \"misc_teleporter_dest\"\n" ); - REQUIRE( converted2[2] == "\"targetname\" \"tp1\"\n" ); - // - // The z (vertical) is offset by +32 - std::istringstream iss(converted2[1]); - std::string attribute; - std::string coords[2]; - float offsetCoord; - iss >> attribute >> coords[0] >> coords[1] >> offsetCoord; - - // next REQUIRE fails without busy wait - for( int i = 0; i < 10000000; i++ ) - int x = i; - - REQUIRE( attribute == "\"origin\"" ); - REQUIRE( coords[0] == "\"-216.00000" ); - REQUIRE( coords[1] == "-1488.000488" ); - REQUIRE( fabs(-100.00000 - offsetCoord) <= DELTA ); - - SECTION( "When angle unspecified, defaults to 0.0 (converted to 90.0)" ) { - std::istringstream angleStream(converted2[3]); - std::string a; - float angle; - angleStream >> attribute >> a; - a.erase(a.begin()); //removing preceding quote is necessary - std::stringstream out(a); - out >> angle; - REQUIRE( fabs(90.0 - angle) <= DELTA ); - } -} - - - -TEST_CASE( "r2x: a single JumpPad and related Target can be converted", "[EntityConverter]" ) { - - // Instantiate object - EntityConverter ec (PICKUP_FILENAME); - - // Mock up JumpPad entity - std::vector entity; - entity.push_back(" type JumpPad"); - entity.push_back(" String32 target jp1"); - - // Mock up Target entity - std::vector entity2; - entity2.push_back(" type Target"); - entity2.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); - entity2.push_back(" String32 name jp1"); - - // Mock up entity queue - std::queue> q; - q.push( entity ); - q.push( entity2 ); - - // Match related entities (one pair) - ec.extractMapInfo( q ); - - // Convert two entities - std::vector converted = ec.convert(entity); - REQUIRE( converted[0] == "\"classname\" \"trigger_push\"\n" ); - REQUIRE( converted[1] == "\"target\" \"jp1\"\n" ); - - std::vector converted2 = ec.convert(entity2); - REQUIRE( converted2[0] == "\"classname\" \"target_position\"\n" ); - REQUIRE( converted2[1] == "\"origin\" \"-216.00000 -1488.000488 -132.00000\"\n" ); - REQUIRE( converted2[2] == "\"targetname\" \"jp1\"\n" ); -} - - - -TEST_CASE( "r2x: a single PointLight entity can be converted", "[EntityConverter]" ) { - - // Instantiate object - EntityConverter ec (PICKUP_FILENAME); - - // Mock up entity - std::vector entity; - entity.push_back(" type PointLight"); - entity.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); - entity.push_back(" ColourXRGB32 color ffffc400"); - entity.push_back(" Float intensity 1.500000"); - entity.push_back(" Float nearAttenuation 32.000000"); - entity.push_back(" Float farAttenuation 160.000000"); - - // Mock up entity queue - std::queue> q; - q.push( entity ); - - // Match related entities (none) - ec.extractMapInfo( q ); - - // Convert a single entity - std::vector converted = ec.convert(entity); - - REQUIRE( converted[0] == "\"classname\" \"light\"\n" ); - REQUIRE( converted[1] == "\"origin\" \"-216.00000 -1488.000488 -132.00000\"\n" ); - REQUIRE( converted[2] == "\"light\" \"75\"\n" ); - - INFO( converted[3] ); - std::istringstream iss(converted[3]); - std::string attribute; - std::string r; - float red; - float green; - float blue; - iss >> attribute >> r >> green >> blue; - r.erase(r.begin()); //removing preceding quote is necessary - std::stringstream redStream(r); - redStream >> red; - - REQUIRE( attribute == "\"_color\"" ); - - REQUIRE( fabs( 1.0 - red) <= DELTA ); - REQUIRE( fabs( 0.768627 - green) <= DELTA ); - REQUIRE( fabs( 0.0 - blue) <= DELTA ); -} - - -TEST_CASE( "r2x: PointLight defaults to white light of typical intensity", "[EntityConverter]" ) { - - // Instantiate object - EntityConverter ec (PICKUP_FILENAME); - - // Mock up entity - std::vector entity; - entity.push_back(" type PointLight"); - entity.push_back(" Vector3 position -216.00000 -132.00000 -1488.000488"); - - // Mock up entity queue - std::queue> q; - q.push( entity ); - - // Match related entities (none) - ec.extractMapInfo( q ); - - // Convert a single entity - std::vector converted = ec.convert(entity); - - REQUIRE( converted[0] == "\"classname\" \"light\"\n" ); - REQUIRE( converted[1] == "\"origin\" \"-216.00000 -1488.000488 -132.00000\"\n" ); - REQUIRE( converted[2] == "\"light\" \"50\"\n" ); - - INFO( converted[3] ); - std::istringstream iss(converted[3]); - std::string attribute; - std::string r; - float red; - float green; - float blue; - iss >> attribute >> r >> green >> blue; - r.erase(r.begin()); //removing preceding quote is necessary - std::stringstream redStream(r); - redStream >> red; - - REQUIRE( attribute == "\"_color\"" ); - - REQUIRE( fabs( 0.0 - red) <= DELTA ); - REQUIRE( fabs( 0.0 - green) <= DELTA ); - REQUIRE( fabs( 0.0 - blue) <= DELTA ); - -} - - - - - - +#include "catch-entityconverter.cpp" #endif //CATCH_CONFIG_MAIN