reflex2q3/ReflexToQ3/test/catch.cpp

452 lines
13 KiB
C++
Raw Normal View History

/*
* =====================================================================================
*
* Filename: catch.cpp
*
* Description: Unit Tests for EntityConverter
*
* Version: 0.1
* Created: 07/03/2017 08:25:04 PM
* Revision: none
* Compiler: gcc
*
* Author: suhrke@teknik.io
*
* =====================================================================================
*/
#ifndef CATCH_CONFIG_MAIN
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include <cmath>
#include <queue>
#include <vector>
#include <sstream>
#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<std::string> entity;
entity.push_back(" type NotAType");
// Mock up entity queue
std::queue<std::vector<std::string>> q;
q.push( entity );
// Match related entities (none)
ec.extractMapInfo( q );
// Convert a single entity
std::vector<std::string> 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<std::string> 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<std::vector<std::string>> q;
q.push( entity );
// Match related entities (none)
ec.extractMapInfo( q );
// Convert a single entity
std::vector<std::string> converted = ec.convert(entity);
REQUIRE( converted[0] == "\"classname\" \"weapon_grenadelauncher\"\n" );
2017-07-06 04:30:22 +05:30
// 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" );
2017-07-06 04:30:22 +05:30
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<std::string> 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<std::string> 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<std::vector<std::string>> 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<std::string> unused = ec.convert(worldspawn);
std::vector<std::string> 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" );
REQUIRE( converted[4] == "\"angle\" \"180.00000\"\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( "Encountering a new worldspawn reenables all modes" ) {
std::vector<std::string> basicWorldspawn;
basicWorldspawn.push_back(" type WorldSpawn");
std::vector<std::string> 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<std::string> u = ec.convert(basicWorldspawn);
std::vector<std::string> 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<std::string> 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<std::vector<std::string>> q;
q.push( entity );
// Match related entities (none)
ec.extractMapInfo( q );
// Convert a single entity
std::vector<std::string> converted = ec.convert(entity);
REQUIRE( converted[0] == "\"classname\" \"info_player_team1\"\n" );
REQUIRE( converted[2] == "\"angle\" \"180.00000\"\n" );
2017-07-06 04:30:22 +05:30
// 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<std::string> 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<std::vector<std::string>> q;
q.push( entity );
// Match related entities (none)
ec.extractMapInfo( q );
// Convert a single entity
std::vector<std::string> converted = ec.convert(entity);
REQUIRE( converted[0] == "\"classname\" \"info_player_deathmatch\"\n" );
REQUIRE( converted[2] == "\"angle\" \"180.00000\"\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<std::string> entity;
entity.push_back(" type RaceStart");
// Mock up entity queue
std::queue<std::vector<std::string>> q;
q.push( entity );
// Match related entities (none)
ec.extractMapInfo( q );
// Convert a single entity
std::vector<std::string> 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<std::string> entity;
entity.push_back(" type RaceFinish");
// Mock up entity queue
std::queue<std::vector<std::string>> q;
q.push( entity );
// Match related entities (none)
ec.extractMapInfo( q );
// Convert a single entity
std::vector<std::string> 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<std::string> entity;
entity.push_back(" type Teleporter");
entity.push_back(" String32 target tp1");
// Mock up Target entity
std::vector<std::string> 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<std::vector<std::string>> q;
q.push( entity );
q.push( entity2 );
// Match related entities (one pair)
ec.extractMapInfo( q );
// Convert two entities
std::vector<std::string> converted = ec.convert(entity);
REQUIRE( converted[0] == "\"classname\" \"trigger_teleport\"\n" );
REQUIRE( converted[1] == "\"target\" \"tp1\"\n" );
std::vector<std::string> converted2 = ec.convert(entity2);
REQUIRE( converted2[0] == "\"classname\" \"misc_teleporter_dest\"\n" );
REQUIRE( converted2[2] == "\"targetname\" \"tp1\"\n" );
//
2017-07-06 04:30:22 +05:30
// 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
2017-07-05 17:52:14 +05:30
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 );
}
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<std::string> entity;
entity.push_back(" type JumpPad");
entity.push_back(" String32 target jp1");
// Mock up Target entity
std::vector<std::string> 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<std::vector<std::string>> q;
q.push( entity );
q.push( entity2 );
// Match related entities (one pair)
ec.extractMapInfo( q );
// Convert two entities
std::vector<std::string> converted = ec.convert(entity);
REQUIRE( converted[0] == "\"classname\" \"trigger_push\"\n" );
REQUIRE( converted[1] == "\"target\" \"jp1\"\n" );
std::vector<std::string> 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<std::string> 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<std::vector<std::string>> q;
q.push( entity );
// Match related entities (none)
ec.extractMapInfo( q );
// Convert a single entity
std::vector<std::string> 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 );
}
#endif //CATCH_CONFIG_MAIN