Reorganized, expanded pickup file to include other entities, now .ent
This commit is contained in:
16
test/cases-face/parser-face-3indices.txt
Normal file
16
test/cases-face/parser-face-3indices.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 5 2 7 0xffffffff common/materials/metal/aluminum
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 6 5 7 0xffffffff common/materials/metal/aluminum
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 1 2 4 0xff727278 common/materials/stone/stone
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 3 1 4 0xff727278 common/materials/stone/stone
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 0 3 4 0xff727278 common/materials/stone/stone
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 4 2 5 0xff727278 common/materials/stone/stone
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 0 4 6 0xff727278 common/materials/stone/stone
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 4 5 6 0xff727278 common/materials/stone/stone
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 5 2 6 0xff727278 common/materials/stone/stone
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 2 0 4 0xffa5a5a5 common/materials/metal/p_metal3
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 1 3 5 0xffa5a5a5 common/materials/metal/p_metal3
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 1 0 3 0xff727278 common/materials/stone/stone
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 3 0 6 0xff727278 common/materials/stone/stone
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 0 4 7 0xff727278 common/materials/stone/stone
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 3 6 7 0xff727278 common/materials/stone/stone
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 6 0 7 0xff727278 common/materials/stone/stone
|
10
test/cases-face/parser-face-4indices.txt
Normal file
10
test/cases-face/parser-face-4indices.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 3 1 0 4 0xffffffff common/materials/metal/aluminum
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 0 1 2 5 0xffffffff common/materials/metal/aluminum
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 4 0 5 6 0xffffffff common/materials/metal/aluminum
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 2 1 3 7 0xffffffff common/materials/metal/aluminum
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 3 4 6 7 0xffffffff common/materials/metal/aluminum"
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 0 3 1 4 0xffa5a5a5 common/materials/metal/p_metal3
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 3 0 2 5 0xffa5a5a5 common/materials/metal/p_metal3
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 2 4 1 5 0xffa5a5a5 common/materials/metal/p_metal3
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 0 1 2 4 0xff727278 common/materials/stone/stone
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 2 1 3 7 0xff727278 common/materials/stone/stone
|
2
test/cases-face/parser-face-5indices.txt
Normal file
2
test/cases-face/parser-face-5indices.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 2 7 5 7 4 0xff727278 common/materials/stone/stone
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 0 6 2 1 3 0xff727278 common/materials/stone/stone
|
6
test/cases-face/parser-face-nomaterial-0.txt
Normal file
6
test/cases-face/parser-face-nomaterial-0.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 0 1 2 3 0x00000000
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 6 5 4 7 0x00000000
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 2 1 5 6 0x00000000
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 0 3 7 4 0x00000000
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 3 2 6 7 0x00000000
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 1 0 4 5 0x00000000
|
510
test/catch-entityconverter.cpp
Normal file
510
test/catch-entityconverter.cpp
Normal file
@@ -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 <cmath>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
#include "EntityConverter.hpp"
|
||||
|
||||
#define ENTITY_FILENAME "r2xonotic.ent"
|
||||
#define DELTA 0.00001
|
||||
|
||||
|
||||
|
||||
TEST_CASE( "r2x: Unsupported entity types cause return of empty vector", "[EntityConverter]" ) {
|
||||
|
||||
// Instantiate object
|
||||
EntityConverter ec (ENTITY_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 (ENTITY_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" );
|
||||
|
||||
// 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 (ENTITY_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" );
|
||||
|
||||
// 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<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 (ENTITY_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" );
|
||||
|
||||
// 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 (ENTITY_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" );
|
||||
|
||||
// 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 (ENTITY_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 (ENTITY_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 (ENTITY_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" );
|
||||
//
|
||||
// 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 (ENTITY_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 (ENTITY_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 );
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE( "r2x: PointLight defaults to white light of typical intensity", "[EntityConverter]" ) {
|
||||
|
||||
// Instantiate object
|
||||
EntityConverter ec (ENTITY_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");
|
||||
|
||||
// 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\" \"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 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
159
test/catch-parser.cpp
Normal file
159
test/catch-parser.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
#include "oopless-parser.hpp"
|
||||
#include "catch.hpp"
|
||||
#include <iostream>
|
||||
|
||||
std::vector<TFace> getfaces(const std::string &test) {
|
||||
using namespace std;
|
||||
stringstream ss;
|
||||
ss << test;
|
||||
return parse_face<stringstream>(ss);
|
||||
}
|
||||
|
||||
TEST_CASE ("face parsing case: faces with 3 indices", "[Parser]" ) {
|
||||
std::string sample = " 0.000000 0.000000 1.000000 1.000000 0.000000 6 0 7 0xff727278 common/materials/stone/stone";
|
||||
struct TFace f = getfaces(sample).front();
|
||||
REQUIRE (f.m_Indices.size() == 3);
|
||||
}
|
||||
|
||||
TEST_CASE ("face parsing case: faces with 4 indices", "[Parser]") {
|
||||
std::string sample = " 0.000000 0.000000 1.000000 1.000000 0.000000 3 1 0 4 0xffffffff common/materials/metal/aluminum";
|
||||
struct TFace f = getfaces(sample).front();
|
||||
REQUIRE (f.m_Indices.size() == 4);
|
||||
}
|
||||
|
||||
TEST_CASE ("face parsing case: faces with 5 indices", "[Parser]") {
|
||||
std::string sample = " 0.000000 0.000000 1.000000 1.000000 0.000000 2 7 5 7 4 0xff727278 common/materials/stone/stone";
|
||||
struct TFace f = getfaces(sample).front();
|
||||
REQUIRE (f.m_Indices.size() == 5);
|
||||
}
|
||||
|
||||
TEST_CASE ("face parsing case: faces with 9 indices", "[Parser]") {
|
||||
std::string sample = " 0.000000 0.000000 1.000000 1.000000 0.000000 2 7 5 7 4 7 5 7 4 0xff727278 common/materials/stone/stone";
|
||||
struct TFace f = getfaces(sample).front();
|
||||
REQUIRE (f.m_Indices.size() == 9);
|
||||
}
|
||||
|
||||
TEST_CASE("face parsing case: faces with no material", "[Parser]") {
|
||||
std::string sample =
|
||||
" 0.000000 0.000000 1.000000 1.000000 0.000000 1 0 4 5 0x00000000 ";
|
||||
std::string answer; //empty string
|
||||
struct TFace f = getfaces(sample).front();
|
||||
REQUIRE (f.m_Material == answer);
|
||||
}
|
||||
|
||||
TEST_CASE("face parsing case: face's material name is preserved", "[Parser]") {
|
||||
std::string sample =
|
||||
" 0.000000 0.000000 1.000000 1.000000 0.000000 3 1 0 4 0xffffffff common/materials/metal/aluminum";
|
||||
std::string answer = "common/materials/metal/aluminum";
|
||||
struct TFace f = getfaces(sample).front();
|
||||
REQUIRE (f.m_Material == answer);
|
||||
}
|
||||
|
||||
TEST_CASE("face parsing case: face's color code is preserved", "[Parser]") {
|
||||
std::string sample =
|
||||
" 0.000000 0.000000 1.000000 1.000000 0.000000 2 4 1 5 0xffa5a5a5 common/materials/metal/p_metal3";
|
||||
std::string answer = "0xffa5a5a5";
|
||||
struct TFace f = getfaces(sample).front();
|
||||
REQUIRE (f.hex == answer);
|
||||
}
|
||||
|
||||
TEST_CASE("brush parser case: returns populated Vertices and Faces list", "[Parser]") {
|
||||
std::string sample = " vertices\n\
|
||||
-23.000000 -20.000000 15.000000\n\
|
||||
9.000000 -20.000000 15.000000\n\
|
||||
9.000000 -20.000000 -17.000000\n\
|
||||
-15.000000 -24.000000 -9.000000\n\
|
||||
-23.000000 -20.000000 -17.000000\n\
|
||||
1.000000 -24.000000 7.000000\n\
|
||||
1.000000 -24.000000 -9.000000\n\
|
||||
-15.000000 -24.000000 7.000000\n\
|
||||
faces\n\
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 0 1 2 4 0xff888888 common/materials/metal/p_metal3\n\
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 3 4 2 6 0xff888888 common/materials/metal/p_metal3\n\
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 2 1 5 6 0xff888888 common/materials/metal/p_metal3\n\
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 0 4 3 7 0xff888888 common/materials/metal/p_metal3\n\
|
||||
0.000000 0.000000 1.000000 1.000000 131.810318 5 1 0 7 0xff888888 common/materials/metal/p_metal3\n\
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 3 6 5 7 0xff888888 common/materials/metal/p_metal3";
|
||||
std::stringstream ss;
|
||||
ss << sample;
|
||||
struct TBrush b = parse_brush<std::stringstream>(ss);
|
||||
REQUIRE ((b.m_Vertices.size() == 8 && b.m_Faces.size() == 6));
|
||||
}
|
||||
|
||||
TEST_CASE("brush parser case: returns empty when given empty input", "[Parser]") {
|
||||
std::string empty;
|
||||
std::stringstream ss;
|
||||
ss << empty;
|
||||
struct TBrush b = parse_brush<std::stringstream>(ss);
|
||||
REQUIRE ((b.m_Vertices.size() == 0 && b.m_Faces.size() == 0));
|
||||
}
|
||||
|
||||
TEST_CASE("get entity case: recognizes brush entites", "[Parser]") {
|
||||
std::string sample = " type JumpPad\n\
|
||||
String32 target jp2\n\
|
||||
brush\n\
|
||||
vertices\n\
|
||||
324.000000 36.000000 -228.000000\n\
|
||||
352.000000 36.000000 -228.000000\n\
|
||||
352.000000 36.000000 -380.000000\n\
|
||||
324.000000 36.000000 -380.000000\n\
|
||||
324.000000 32.000000 -228.000000\n\
|
||||
352.000000 32.000000 -228.000000\n\
|
||||
352.000000 32.000000 -380.000000\n\
|
||||
324.000000 32.000000 -380.000000\n\
|
||||
faces\n\
|
||||
0.000000 0.000000 -0.250000 -0.000000 270.000000 0 1 2 3 0x00000000 \n\
|
||||
0.000000 0.000000 -0.250000 -0.000000 0.000000 6 5 4 7 0x00000000 \n\
|
||||
0.000000 0.000000 -0.250000 -0.000000 0.000000 2 1 5 6 0x00000000 \n\
|
||||
0.000000 0.000000 -0.250000 -0.000000 0.000000 0 3 7 4 0x00000000 \n\
|
||||
0.000000 0.000000 -0.250000 -0.000000 0.000000 3 2 6 7 0x00000000 \n\
|
||||
0.000000 0.000000 -0.250000 -0.000000 0.000000 1 0 4 5 0x00000000 ";
|
||||
std::stringstream ss;
|
||||
ss << sample;
|
||||
std::vector<std::string> ent = get_entity<std::stringstream>(ss);
|
||||
unsigned int count = 0;
|
||||
for (const std::string &x : ent) {
|
||||
if (x.find(KEYWORD_BRUSH) != std::string::npos) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
REQUIRE ((count == 1 && ent.size() == 19));
|
||||
}
|
||||
|
||||
TEST_CASE("get entity case: omits unaffiliated brush") {
|
||||
std::string sample = " type WorldSpawn\n\
|
||||
String32 targetGameOverCamera end\n\
|
||||
ColourXRGB32 colorTeamA ff801313\n\
|
||||
ColourXRGB32 fogColor ff7f5122\n\
|
||||
Float fogDistanceEnd 3500.000000\n\
|
||||
String256 title Static Discharge\n\
|
||||
UInt8 playersMax 6\n\
|
||||
brush\n\
|
||||
vertices\n\
|
||||
-19.000000 28.000000 23.000000\n\
|
||||
29.000000 28.000000 23.000000\n\
|
||||
29.000000 28.000000 -25.000000\n\
|
||||
-19.000000 28.000000 -25.000000\n\
|
||||
-19.000000 -20.000000 23.000000\n\
|
||||
29.000000 -20.000000 23.000000\n\
|
||||
29.000000 -20.000000 -25.000000\n\
|
||||
-19.000000 -20.000000 -25.000000\n\
|
||||
faces\n\
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 0 1 2 3 0xff888888 common/materials/metal/p_metal3\n\
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 6 5 4 7 0xff888888 common/materials/metal/p_metal3\n\
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 2 1 5 6 0xff888888 common/materials/metal/p_metal3\n\
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 0 3 7 4 0xff888888 common/materials/metal/p_metal3\n\
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 3 2 6 7 0xff888888 common/materials/metal/p_metal3\n\
|
||||
0.000000 0.000000 1.000000 1.000000 0.000000 1 0 4 5 0xff888888 common/materials/metal/p_metal3";
|
||||
std::stringstream ss;
|
||||
ss << sample;
|
||||
std::vector<std::string> ent = get_entity<std::stringstream>(ss);
|
||||
unsigned int count = 0;
|
||||
for (const std::string &x : ent) {
|
||||
if (x.find(KEYWORD_BRUSH) != std::string::npos) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
REQUIRE ((count == 0 && ent.size() == 7));
|
||||
}
|
||||
|
26
test/catch.cpp
Normal file
26
test/catch.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* =====================================================================================
|
||||
*
|
||||
* Filename: catch.cpp
|
||||
*
|
||||
* Description: Unit Tests using the Catch framework
|
||||
*
|
||||
* Version: 1.0
|
||||
* 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 "catch-parser.cpp"
|
||||
#include "catch-entityconverter.cpp"
|
||||
|
||||
|
||||
#endif //CATCH_CONFIG_MAIN
|
||||
|
Reference in New Issue
Block a user