mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-06 19:50:03 -06:00
Created unit tests for profileFile
This commit is contained in:
@@ -47,8 +47,6 @@ namespace scripting { struct LuaLibrary; }
|
||||
|
||||
class Profile {
|
||||
public:
|
||||
Profile();
|
||||
|
||||
void saveCurrentSettingsToProfile(std::string filename);
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,15 +25,10 @@
|
||||
#ifndef __OPENSPACE_CORE___PROFILEFILE___H__
|
||||
#define __OPENSPACE_CORE___PROFILEFILE___H__
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scene/scenelicense.h>
|
||||
#include <ghoul/misc/easing.h>
|
||||
#include <ghoul/misc/exception.h>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <istream>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace ghoul { class Dictionary; }
|
||||
@@ -44,18 +39,15 @@ namespace openspace {
|
||||
namespace documentation { struct Documentation; }
|
||||
namespace scripting { struct LuaLibrary; }
|
||||
|
||||
|
||||
class ProfileFile {
|
||||
public:
|
||||
ProfileFile(std::string filename);
|
||||
~ProfileFile();
|
||||
void readLines(std::function<bool(std::string&)> reader);
|
||||
void readFromFile(std::string filename);
|
||||
void processIndividualLine(bool& insideSection, std::string line);
|
||||
void write(std::ostream& output);
|
||||
void writeToFile(std::string filename);
|
||||
|
||||
//Need a copy constructor here to do a deep copy
|
||||
|
||||
void read();
|
||||
void write();
|
||||
|
||||
void setFilename(std::string filename);
|
||||
const std::string getVersion() const;
|
||||
|
||||
//Methods for updating contents
|
||||
void updateTime();
|
||||
@@ -67,21 +59,24 @@ public:
|
||||
void addMarkNodesLine(std::string line);
|
||||
|
||||
//Methods for getting contents of each section
|
||||
std::string time();
|
||||
std::string camera();
|
||||
std::vector<std::string> modules();
|
||||
std::vector<std::string> assets();
|
||||
std::vector<std::string> properties();
|
||||
std::vector<std::string> keybindings();
|
||||
std::vector<std::string> markNodes();
|
||||
std::string time() const;
|
||||
std::string camera() const;
|
||||
std::vector<std::string> modules() const;
|
||||
std::vector<std::string> assets() const;
|
||||
std::vector<std::string> properties() const;
|
||||
std::vector<std::string> keybindings() const;
|
||||
std::vector<std::string> markNodes() const;
|
||||
|
||||
private:
|
||||
void logError(std::string message);
|
||||
std::string errorString(std::string message);
|
||||
void clearAllFields();
|
||||
bool isBlank(std::string line);
|
||||
int splitByTab(std::string line, std::vector<std::string>& result);
|
||||
size_t splitByTab(std::string line, std::vector<std::string>& result);
|
||||
void verifyRequiredFields(std::string sectionName, std::vector<std::string> fields,
|
||||
std::vector<std::string> standard, unsigned int nFields);
|
||||
|
||||
bool determineSection(std::string line);
|
||||
void parseCurrentSection(std::string line);
|
||||
void (ProfileFile::* parseCurrentSection)(std::string);
|
||||
void parseVersion(std::string line);
|
||||
void parseModule(std::string line);
|
||||
void parseAsset(std::string line);
|
||||
@@ -90,28 +85,34 @@ private:
|
||||
void parseTime(std::string line);
|
||||
void parseCamera(std::string line);
|
||||
void parseMarkNodes(std::string line);
|
||||
void verifyRequiredFields(std::string sectionName, std::vector<std::string> fields,
|
||||
std::vector<std::string> standard, unsigned int nFields);
|
||||
void addAllElements(std::ostream& file, std::vector<std::string>& list);
|
||||
|
||||
const int versionLinesExpected = 1;
|
||||
const int timeLinesExpected = 1;
|
||||
const int cameraLinesExpected = 1;
|
||||
const size_t _versionLinesExpected = 1;
|
||||
const size_t _timeLinesExpected = 1;
|
||||
const size_t _cameraLinesExpected = 1;
|
||||
const size_t _versionFieldsExpected = 1;
|
||||
const size_t _moduleFieldsExpected = 3;
|
||||
const size_t _assetFieldsExpected = 2;
|
||||
const size_t _propertyFieldsExpected = 3;
|
||||
const size_t _keybindingFieldsExpected = 6;
|
||||
const size_t _timeFieldsExpected = 2;
|
||||
const size_t _cameraNavigationFieldsExpected = 8;
|
||||
const size_t _cameraGeoFieldsExpected = 5;
|
||||
const size_t _markNodesFieldsExpected = 1;
|
||||
|
||||
const int versionFieldsExpected = 1;
|
||||
const int moduleFieldsExpected = 3;
|
||||
const int assetFieldsExpected = 2;
|
||||
const int propertyFieldsExpected = 3;
|
||||
const int keybindingFieldsExpected = 6;
|
||||
const int timeFieldsExpected = 2;
|
||||
const int cameraNavigationFieldsExpected = 8;
|
||||
const int cameraGeoFieldsExpected = 5;
|
||||
const int markNodesFieldsExpected = 1;
|
||||
const std::string header_Version = "#Version";
|
||||
const std::string header_Module = "#Module";
|
||||
const std::string header_Asset = "#Asset";
|
||||
const std::string header_Property = "#Property";
|
||||
const std::string header_Keybinding = "#Keybinding";
|
||||
const std::string header_Time = "#Time";
|
||||
const std::string header_Camera = "#Camera";
|
||||
const std::string header_MarkNodes = "#MarkNodes";
|
||||
|
||||
std::string _filename;
|
||||
unsigned int _lineNum = 1;
|
||||
unsigned int _numLinesVersion = 0;
|
||||
unsigned int _numLinesTime = 0;
|
||||
unsigned int _numLinesCamera = 0;
|
||||
size_t _lineNum = 1;
|
||||
size_t _numLinesVersion = 0;
|
||||
size_t _numLinesTime = 0;
|
||||
size_t _numLinesCamera = 0;
|
||||
|
||||
std::string _version;
|
||||
std::string _time;
|
||||
@@ -152,6 +152,9 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/scene/assetmanager.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/scene/assetmanager_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/scene/lightsource.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/scene/profile.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/scene/profilefile.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/scene/profile_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/scene/rotation.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/scene/scale.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/scene/scene.cpp
|
||||
@@ -342,6 +345,8 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/assetloader.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/assetmanager.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/lightsource.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/profile.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/profilefile.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/rotation.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/scale.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/scene/scene.h
|
||||
|
||||
@@ -53,19 +53,6 @@ namespace {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
Profile::Profile()
|
||||
: properties::PropertyOwner({"Scene", "Scene"})
|
||||
, _initializer(std::move(initializer))
|
||||
{
|
||||
_rootDummy.setIdentifier(SceneGraphNode::RootNodeIdentifier);
|
||||
_rootDummy.setScene(this);
|
||||
}
|
||||
|
||||
Profile::~Profile() {
|
||||
clear();
|
||||
_rootDummy.setScene(nullptr);
|
||||
}
|
||||
|
||||
void Profile::saveCurrentSettingsToProfile(std::string filename) {
|
||||
if (! global::configuration.usingProfile) {
|
||||
std::string errorMessage = "Program was not started using a profile, "
|
||||
|
||||
@@ -1,308 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2020 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/scene/profileFile.h>
|
||||
|
||||
#include <openspace/engine/configuration.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/globalscallbacks.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scene/scenelicensewriter.h>
|
||||
#include <openspace/scene/sceneinitializer.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/profiling.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <string>
|
||||
#include <stack>
|
||||
#include <iomanip>
|
||||
#include <cctype>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "ProfileFile";
|
||||
constexpr const char* KeyIdentifier = "Identifier";
|
||||
constexpr const char* KeyParent = "Parent";
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
ProfileFile::ProfileFile(std::string filename)
|
||||
: _filename(filename)
|
||||
{
|
||||
}
|
||||
|
||||
ProfileFile::~ProfileFile() {
|
||||
}
|
||||
|
||||
void ProfileFile::read() {
|
||||
clearAllFields();
|
||||
std::ifstream inFile;
|
||||
inFile.open(_filename, std::ifstream::in);
|
||||
std::string line;
|
||||
_lineNum = 1;
|
||||
bool insideSection = false;
|
||||
|
||||
while (getline(inFile, line)) {
|
||||
if (insideSection) {
|
||||
if (isBlank(line)) {
|
||||
insideSection = false;
|
||||
}
|
||||
else {
|
||||
parseCurrentSection(line);
|
||||
}
|
||||
}
|
||||
else if (line.substr(0, 1) == "#") {
|
||||
if (determineSection(line)) {
|
||||
insideSection = true;
|
||||
}
|
||||
}
|
||||
_lineNum++;
|
||||
}
|
||||
inFile.close();
|
||||
}
|
||||
|
||||
void ProfileFile::clearAllFields() {
|
||||
_numLinesVersion = 0;
|
||||
_numLinesTime = 0;
|
||||
_numLinesCamera = 0;
|
||||
|
||||
_version.clear();
|
||||
_time.clear();
|
||||
_camera.clear();
|
||||
_modules.clear();
|
||||
_assets.clear();
|
||||
_properties.clear();
|
||||
_keybindings.clear();
|
||||
_markNodes.clear();
|
||||
}
|
||||
|
||||
bool ProfileFile::isBlank(std::string line) {
|
||||
char* c = line.c_str();
|
||||
int nonBlanks = 0;
|
||||
while (*c) {
|
||||
if (!isspace(*c)) {
|
||||
nonBlanks++;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
return (nonBlanks == 0);
|
||||
}
|
||||
|
||||
bool ProfileFile::determineSection(std::string line) {
|
||||
|
||||
}
|
||||
|
||||
void ProfileFile::parseCurrentSection(std::string line) {
|
||||
|
||||
}
|
||||
|
||||
void ProfileFile::logError(std::string message) {
|
||||
std::string e = "Error @ line " + std::to_string(_lineNum) + ": ";
|
||||
LERROR(e + message);
|
||||
}
|
||||
|
||||
void ProfileFile::parseVersion(std::string line) {
|
||||
std::vector<std::string> fields;
|
||||
|
||||
if (++_numLinesVersion > versionLinesExpected) {
|
||||
logError("Too many lines in Version section");
|
||||
}
|
||||
if (splitByTab(line, fields) > versionFieldsExpected) {
|
||||
logError("No tabs allowed in Version entry");
|
||||
}
|
||||
else {
|
||||
_version = line;
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileFile::parseModule(std::string line) {
|
||||
std::vector<std::string> fields;
|
||||
|
||||
if (splitByTab(line, fields) != moduleFieldsExpected) {
|
||||
logError(std::to_string(moduleFieldsExpected) +
|
||||
" fields required in a Module entry");
|
||||
}
|
||||
std::vector<std::string> standard = {
|
||||
"module name",
|
||||
"",
|
||||
""
|
||||
};
|
||||
verifyRequiredFields(fields, standard, moduleFieldsExpected);
|
||||
_modules.push_back(line);
|
||||
}
|
||||
|
||||
void ProfileFile::parseAsset(std::string line) {
|
||||
std::vector<std::string> fields;
|
||||
|
||||
if (splitByTab(line, fields) != assetFieldsExpected) {
|
||||
logError(std::to_string(assetFieldsExpected) +
|
||||
" fields required in an Asset entry");
|
||||
}
|
||||
std::vector<std::string> standard = {
|
||||
"asset name",
|
||||
""
|
||||
};
|
||||
verifyRequiredFields(fields, standard, assetFieldsExpected);
|
||||
_assets.push_back(line);
|
||||
}
|
||||
|
||||
void ProfileFile::parseProperty(std::string line) {
|
||||
std::vector<std::string> fields;
|
||||
|
||||
if (splitByTab(line, fields) != propertyFieldsExpected) {
|
||||
logError(std::to_string(propertyFieldsExpected) +
|
||||
" fields required in Property entry");
|
||||
}
|
||||
std::vector<std::string> standard = {
|
||||
"set command",
|
||||
"name",
|
||||
"value"
|
||||
};
|
||||
verifyRequiredFields("Property", fields, standard, propertyFieldsExpected);
|
||||
_properties.push_back(line);
|
||||
}
|
||||
|
||||
void ProfileFile::parseKeybinding(std::string line) {
|
||||
std::vector<std::string> fields;
|
||||
|
||||
if (splitByTab(line, fields) != keybindingFieldsExpected) {
|
||||
logError(std::to_string(keybindingFieldsExpected) +
|
||||
" fields required in Keybinding entry");
|
||||
}
|
||||
std::vector<std::string> standard = {
|
||||
"key",
|
||||
"documentation",
|
||||
"name",
|
||||
"GuiPath",
|
||||
"local(T/F)",
|
||||
"script to execute"
|
||||
};
|
||||
verifyRequiredFields("Keybinding", fields, standard, propertyFieldsExpected);
|
||||
_properties.push_back(line);
|
||||
}
|
||||
|
||||
void ProfileFile::parseTime(std::string line) {
|
||||
std::vector<std::string> fields;
|
||||
|
||||
if (++_numLinesTime > timeLinesExpected) {
|
||||
logError("Too many lines in time section");
|
||||
}
|
||||
if (splitByTab(line, fields) != timeFieldsExpected) {
|
||||
logError(std::to_string(timeFieldsExpected) +
|
||||
" fields required in Time entry");
|
||||
}
|
||||
std::vector<std::string> standard = {
|
||||
"time set type",
|
||||
"time value to set"
|
||||
};
|
||||
verifyRequiredFields("Time", fields, standard, propertyFieldsExpected);
|
||||
_time = line;
|
||||
}
|
||||
|
||||
void ProfileFile::parseCamera(std::string line) {
|
||||
std::vector<std::string> fields;
|
||||
|
||||
if (++_numLinesCamera > cameraLinesExpected) {
|
||||
logError("Too many lines in camera section");
|
||||
}
|
||||
int nFields = splitByTab(line, fields);
|
||||
if (nFields == cameraNavigationFieldsExpected) {
|
||||
std::vector<std::string> standard = {
|
||||
"Type of camera set (setNavigationState)",
|
||||
"setNavigationState Anchor",
|
||||
"",
|
||||
"",
|
||||
"setNavigationState position vector",
|
||||
"",
|
||||
"",
|
||||
""
|
||||
};
|
||||
verifyRequiredFields("Camera", fields, standard, cameraNavigationFieldsExpected);
|
||||
}
|
||||
else if (nFields == cameraGeoFieldsExpected) {
|
||||
std::vector<std::string> standard = {
|
||||
"Type of camera set (goToGeo)",
|
||||
"",
|
||||
"Camera goToGeo Latitude",
|
||||
"Camera goToGeo Longitude",
|
||||
""
|
||||
};
|
||||
verifyRequiredFields("Camera goToGeo", fields, standard,
|
||||
cameraNavigationFieldsExpected);
|
||||
}
|
||||
else {
|
||||
logError(std::to_string(cameraNavigationFieldsExpected) + " or " +
|
||||
std::to_string(cameraGeoFieldsExpected) + " fields required in Camera entry");
|
||||
}
|
||||
_camera = line;
|
||||
}
|
||||
|
||||
void ProfileFile::parseMarkNodes(std::string line) {
|
||||
std::vector<std::string> fields;
|
||||
|
||||
if (splitByTab(line, fields) != markNodesFieldsExpected) {
|
||||
logError(std::to_string(markNodesFieldsExpected) +
|
||||
" field required in an Mark Nodes entry");
|
||||
}
|
||||
std::vector<std::string> standard = {
|
||||
"Mark Interesting Node name"
|
||||
};
|
||||
verifyRequiredFields("Mark Interesting Nodes", fields, standard,
|
||||
markNodesFieldsExpected);
|
||||
_assets.push_back(line);
|
||||
}
|
||||
|
||||
void ProfileFile::verifyRequiredFields(std::string sectionName,
|
||||
std::vector<std::string> fields,
|
||||
std::vector<std::string> standard,
|
||||
unsigned int nFields)
|
||||
{
|
||||
for (unsigned int i = 0; i < fields.size(); i++) {
|
||||
if (!standard[i].empty() && fields[i].empty()) {
|
||||
std::string errMsg = sectionName + " " + standard[i];
|
||||
errMsg += "(arg " + std::to_string(i) + "/" + nFields + ") is required";
|
||||
logError(errMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ProfileFile::splitByTab(std::string line, std::vector<std::string>& result) {
|
||||
std::istringstream iss(line);
|
||||
std::string tmp;
|
||||
result.clear();
|
||||
while(std::getline(iss, tmp, '\t')) {
|
||||
result.push_back(tmp);
|
||||
}
|
||||
return result.size();
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
450
src/scene/profilefile.cpp
Normal file
450
src/scene/profilefile.cpp
Normal file
@@ -0,0 +1,450 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2020 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/scene/profilefile.h>
|
||||
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/profiling.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <cctype>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "ProfileFile";
|
||||
constexpr const char* KeyIdentifier = "Identifier";
|
||||
constexpr const char* KeyParent = "Parent";
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
void ProfileFile::readFromFile(std::string filename) {
|
||||
clearAllFields();
|
||||
std::ifstream inFile;
|
||||
|
||||
try {
|
||||
inFile.open(filename, std::_Ios_Openmode::_S_in);
|
||||
}
|
||||
catch (std::ifstream::failure& e) {
|
||||
throw ghoul::RuntimeError("Exception opening profile file for read: "
|
||||
+ filename, "profileFile");
|
||||
}
|
||||
|
||||
try {
|
||||
readLines([&inFile] (std::string& line) {
|
||||
if (getline(inFile, line))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
}
|
||||
catch (std::ifstream::failure& e) {
|
||||
throw ghoul::RuntimeError(errorString("Read error using getline"),
|
||||
"profileFile");
|
||||
}
|
||||
|
||||
try {
|
||||
inFile.close();
|
||||
}
|
||||
catch (std::ifstream::failure& e) {
|
||||
throw ghoul::RuntimeError("Exception closing profile file after read: "
|
||||
+ filename, "profileFile");
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileFile::readLines(std::function<bool(std::string&)> reader) {
|
||||
std::string line;
|
||||
bool insideSection = false;
|
||||
_lineNum = 1;
|
||||
|
||||
while (reader(line)) {
|
||||
processIndividualLine(insideSection, line);
|
||||
_lineNum++;
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileFile::processIndividualLine(bool& insideSection, std::string line) {
|
||||
if (insideSection) {
|
||||
if (isBlank(line)) {
|
||||
insideSection = false;
|
||||
}
|
||||
else {
|
||||
if (parseCurrentSection != nullptr) {
|
||||
(this->*parseCurrentSection)(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line.substr(0, 1) == "#") {
|
||||
if (determineSection(line)) {
|
||||
insideSection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileFile::writeToFile(std::string filename) {
|
||||
std::ofstream outFile;
|
||||
try {
|
||||
outFile.open(filename, std::ofstream::out | std::ofstream::app);
|
||||
}
|
||||
catch (std::ofstream::failure& e) {
|
||||
LERROR("Exception opening profile file for write: " + filename);
|
||||
}
|
||||
|
||||
try {
|
||||
write(outFile);
|
||||
}
|
||||
catch (std::ofstream::failure& e) {
|
||||
LERROR("Data write error to file: " + filename);
|
||||
}
|
||||
|
||||
try {
|
||||
outFile.close();
|
||||
}
|
||||
catch (std::ofstream::failure& e) {
|
||||
LERROR("Exception closing profile file after write: " + filename);
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileFile::write(std::ostream& output) {
|
||||
output << header_Version << std::endl;
|
||||
output << _version << std::endl << std::endl;
|
||||
output << header_Module << std::endl;
|
||||
addAllElements(output, _modules);
|
||||
output << std::endl;
|
||||
output << header_Asset << std::endl;
|
||||
addAllElements(output, _assets);
|
||||
output << std::endl;
|
||||
output << header_Property << std::endl;
|
||||
addAllElements(output, _properties);
|
||||
output << std::endl;
|
||||
output << header_Keybinding << std::endl;
|
||||
addAllElements(output, _keybindings);
|
||||
output << std::endl;
|
||||
output << header_Time << std::endl;
|
||||
output << _time << std::endl << std::endl;
|
||||
output << header_Camera << std::endl;
|
||||
output << _camera << std::endl;
|
||||
output << header_MarkNodes << std::endl;
|
||||
addAllElements(output, _markNodes);
|
||||
}
|
||||
|
||||
const std::string ProfileFile::getVersion() const {
|
||||
return _version;
|
||||
}
|
||||
|
||||
void ProfileFile::addAllElements(std::ostream& file, std::vector<std::string>& list) {
|
||||
for (auto s : list) {
|
||||
file << s << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileFile::clearAllFields() {
|
||||
_numLinesVersion = 0;
|
||||
_numLinesTime = 0;
|
||||
_numLinesCamera = 0;
|
||||
|
||||
_version.clear();
|
||||
_time.clear();
|
||||
_camera.clear();
|
||||
_modules.clear();
|
||||
_assets.clear();
|
||||
_properties.clear();
|
||||
_keybindings.clear();
|
||||
_markNodes.clear();
|
||||
}
|
||||
|
||||
bool ProfileFile::isBlank(std::string line) {
|
||||
char* c = const_cast<char*>(line.c_str());
|
||||
int nonBlanks = 0;
|
||||
while (*c) {
|
||||
if (!isspace(*c)) {
|
||||
nonBlanks++;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
return (nonBlanks == 0);
|
||||
}
|
||||
|
||||
bool ProfileFile::determineSection(std::string line) {
|
||||
bool foundSection = true;
|
||||
|
||||
if (line.compare(header_Version) == 0) {
|
||||
parseCurrentSection = &ProfileFile::parseVersion;
|
||||
}
|
||||
else if (line.compare(header_Module) == 0) {
|
||||
parseCurrentSection = &ProfileFile::parseModule;
|
||||
}
|
||||
else if (line.compare(header_Asset) == 0) {
|
||||
parseCurrentSection = &ProfileFile::parseAsset;
|
||||
}
|
||||
else if (line.compare(header_Property) == 0) {
|
||||
parseCurrentSection = &ProfileFile::parseProperty;
|
||||
}
|
||||
else if (line.compare(header_Keybinding) == 0) {
|
||||
parseCurrentSection = &ProfileFile::parseKeybinding;
|
||||
}
|
||||
else if (line.compare(header_Time) == 0) {
|
||||
parseCurrentSection = &ProfileFile::parseTime;
|
||||
}
|
||||
else if (line.compare(header_Camera) == 0) {
|
||||
parseCurrentSection = &ProfileFile::parseCamera;
|
||||
}
|
||||
else if (line.compare(header_MarkNodes) == 0) {
|
||||
parseCurrentSection = &ProfileFile::parseMarkNodes;
|
||||
}
|
||||
else {
|
||||
throw ghoul::RuntimeError(errorString("Invalid section header '" + line + "'"),
|
||||
"profileFile");
|
||||
foundSection = false;
|
||||
}
|
||||
return foundSection;
|
||||
}
|
||||
|
||||
std::string ProfileFile::errorString(std::string message) {
|
||||
std::string e = "Error @ line " + std::to_string(_lineNum) + ": ";
|
||||
return e + message;
|
||||
}
|
||||
|
||||
std::string ProfileFile::time() const {
|
||||
return _time;
|
||||
}
|
||||
|
||||
std::string ProfileFile::camera() const {
|
||||
return _camera;
|
||||
}
|
||||
|
||||
std::vector<std::string> ProfileFile::modules() const {
|
||||
return _modules;
|
||||
}
|
||||
|
||||
std::vector<std::string> ProfileFile::assets() const {
|
||||
return _assets;
|
||||
}
|
||||
|
||||
std::vector<std::string> ProfileFile::properties() const {
|
||||
return _properties;
|
||||
}
|
||||
|
||||
std::vector<std::string> ProfileFile::keybindings() const {
|
||||
return _keybindings;
|
||||
}
|
||||
|
||||
std::vector<std::string> ProfileFile::markNodes() const {
|
||||
return _markNodes;
|
||||
}
|
||||
|
||||
void ProfileFile::parseVersion(std::string line) {
|
||||
std::vector<std::string> fields;
|
||||
|
||||
if (++_numLinesVersion > _versionLinesExpected) {
|
||||
throw ghoul::RuntimeError(errorString("Too many lines in Version section"),
|
||||
"profileFile");
|
||||
}
|
||||
if (splitByTab(line, fields) > _versionFieldsExpected) {
|
||||
throw ghoul::RuntimeError(errorString("No tabs allowed in Version entry"),
|
||||
"profileFile");
|
||||
}
|
||||
else {
|
||||
_version = line;
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileFile::parseModule(std::string line) {
|
||||
std::vector<std::string> fields;
|
||||
|
||||
if (splitByTab(line, fields) != _moduleFieldsExpected) {
|
||||
throw ghoul::RuntimeError(errorString(std::to_string(_moduleFieldsExpected) +
|
||||
" fields required in a Module entry"), "profileFile");
|
||||
}
|
||||
std::vector<std::string> standard = {
|
||||
"module name",
|
||||
"",
|
||||
""
|
||||
};
|
||||
verifyRequiredFields("Module", fields, standard, _moduleFieldsExpected);
|
||||
_modules.push_back(line);
|
||||
}
|
||||
|
||||
void ProfileFile::parseAsset(std::string line) {
|
||||
std::vector<std::string> fields;
|
||||
|
||||
if (splitByTab(line, fields) != _assetFieldsExpected) {
|
||||
throw ghoul::RuntimeError(errorString(std::to_string(_assetFieldsExpected) +
|
||||
" fields required in an Asset entry"), "profileFile");
|
||||
}
|
||||
std::vector<std::string> standard = {
|
||||
"asset name",
|
||||
""
|
||||
};
|
||||
verifyRequiredFields("Asset", fields, standard, _assetFieldsExpected);
|
||||
_assets.push_back(line);
|
||||
}
|
||||
|
||||
void ProfileFile::parseProperty(std::string line) {
|
||||
std::vector<std::string> fields;
|
||||
|
||||
if (splitByTab(line, fields) != _propertyFieldsExpected) {
|
||||
throw ghoul::RuntimeError(errorString(std::to_string(_propertyFieldsExpected) +
|
||||
" fields required in Property entry"), "profileFile");
|
||||
}
|
||||
std::vector<std::string> standard = {
|
||||
"set command",
|
||||
"name",
|
||||
"value"
|
||||
};
|
||||
verifyRequiredFields("Property", fields, standard, _propertyFieldsExpected);
|
||||
_properties.push_back(line);
|
||||
}
|
||||
|
||||
void ProfileFile::parseKeybinding(std::string line) {
|
||||
std::vector<std::string> fields;
|
||||
|
||||
if (splitByTab(line, fields) != _keybindingFieldsExpected) {
|
||||
throw ghoul::RuntimeError(errorString(std::to_string(_keybindingFieldsExpected)
|
||||
+ " fields required in Keybinding entry"), "profileFile");
|
||||
}
|
||||
std::vector<std::string> standard = {
|
||||
"key",
|
||||
"documentation",
|
||||
"name",
|
||||
"GuiPath",
|
||||
"local(T/F)",
|
||||
"script to execute"
|
||||
};
|
||||
verifyRequiredFields("Keybinding", fields, standard, _keybindingFieldsExpected);
|
||||
_keybindings.push_back(line);
|
||||
}
|
||||
|
||||
void ProfileFile::parseTime(std::string line) {
|
||||
std::vector<std::string> fields;
|
||||
|
||||
if (++_numLinesTime > _timeLinesExpected) {
|
||||
throw ghoul::RuntimeError(errorString("Too many lines in time section"),
|
||||
"profileFile");
|
||||
}
|
||||
if (splitByTab(line, fields) != _timeFieldsExpected) {
|
||||
throw ghoul::RuntimeError(errorString(std::to_string(_timeFieldsExpected) +
|
||||
" fields required in Time entry"), "profileFile");
|
||||
}
|
||||
std::vector<std::string> standard = {
|
||||
"time set type",
|
||||
"time value to set"
|
||||
};
|
||||
verifyRequiredFields("Time", fields, standard, _timeFieldsExpected);
|
||||
_time = line;
|
||||
}
|
||||
|
||||
void ProfileFile::parseCamera(std::string line) {
|
||||
std::vector<std::string> fields;
|
||||
|
||||
if (++_numLinesCamera > _cameraLinesExpected) {
|
||||
throw ghoul::RuntimeError(errorString("Too many lines in camera section"),
|
||||
"profileFile");
|
||||
}
|
||||
size_t nFields = splitByTab(line, fields);
|
||||
if (nFields == _cameraNavigationFieldsExpected) {
|
||||
std::vector<std::string> standard = {
|
||||
"Type of camera set (setNavigationState)",
|
||||
"setNavigationState Anchor",
|
||||
"",
|
||||
"",
|
||||
"setNavigationState position vector",
|
||||
"",
|
||||
"",
|
||||
""
|
||||
};
|
||||
verifyRequiredFields("Camera navigation", fields, standard,
|
||||
_cameraNavigationFieldsExpected);
|
||||
}
|
||||
else if (nFields == _cameraGeoFieldsExpected) {
|
||||
std::vector<std::string> standard = {
|
||||
"Type of camera set (goToGeo)",
|
||||
"",
|
||||
"Camera goToGeo Latitude",
|
||||
"Camera goToGeo Longitude",
|
||||
""
|
||||
};
|
||||
verifyRequiredFields("Camera goToGeo", fields, standard,
|
||||
_cameraGeoFieldsExpected);
|
||||
}
|
||||
else {
|
||||
throw ghoul::RuntimeError(errorString(std::to_string(
|
||||
_cameraNavigationFieldsExpected) + " or " + std::to_string(
|
||||
_cameraGeoFieldsExpected) + " fields required in Camera entry"),
|
||||
"profileFile");
|
||||
}
|
||||
_camera = line;
|
||||
}
|
||||
|
||||
void ProfileFile::parseMarkNodes(std::string line) {
|
||||
std::vector<std::string> fields;
|
||||
|
||||
if (splitByTab(line, fields) != _markNodesFieldsExpected) {
|
||||
throw ghoul::RuntimeError(errorString(std::to_string(_markNodesFieldsExpected) +
|
||||
" field required in an Mark Nodes entry"), "profileFile");
|
||||
}
|
||||
std::vector<std::string> standard = {
|
||||
"Mark Interesting Node name"
|
||||
};
|
||||
verifyRequiredFields("Mark Interesting Nodes", fields, standard,
|
||||
_markNodesFieldsExpected);
|
||||
_markNodes.push_back(line);
|
||||
}
|
||||
|
||||
void ProfileFile::verifyRequiredFields(std::string sectionName,
|
||||
std::vector<std::string> fields,
|
||||
std::vector<std::string> standard,
|
||||
unsigned int nFields)
|
||||
{
|
||||
for (unsigned int i = 0; i < fields.size(); i++) {
|
||||
if (!standard[i].empty() && fields[i].empty()) {
|
||||
std::string errMsg = sectionName + " " + standard[i];
|
||||
errMsg += "(arg " + std::to_string(i) + "/";
|
||||
errMsg += std::to_string(nFields) + ") is required";
|
||||
throw ghoul::RuntimeError(errorString(errMsg), "profileFile");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t ProfileFile::splitByTab(std::string line, std::vector<std::string>& result) {
|
||||
std::istringstream iss(line);
|
||||
std::string tmp;
|
||||
result.clear();
|
||||
while (getline(iss, tmp, '\t')) {
|
||||
result.push_back(tmp);
|
||||
}
|
||||
//Insert additional empty fields only for the case of tab delimiters at end of
|
||||
// string without populated field(s)
|
||||
size_t nTabs = std::count(line.begin(), line.end(), '\t');
|
||||
for (size_t i = 0; i < (nTabs - result.size() + 1); ++i) {
|
||||
result.push_back("");
|
||||
}
|
||||
return result.size();
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -34,6 +34,7 @@ add_executable(
|
||||
test_lrucache.cpp
|
||||
test_luaconversions.cpp
|
||||
test_optionproperty.cpp
|
||||
profile/test_profilefile.cpp
|
||||
test_rawvolumeio.cpp
|
||||
test_scriptscheduler.cpp
|
||||
test_spicemanager.cpp
|
||||
|
||||
268
tests/profile/test_profilefile.cpp
Normal file
268
tests/profile/test_profilefile.cpp
Normal file
@@ -0,0 +1,268 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2020 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include "catch2/catch.hpp"
|
||||
|
||||
#include "openspace/scene/profilefile.h"
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/misc/exception.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace openspace;
|
||||
|
||||
namespace {
|
||||
}
|
||||
|
||||
struct testProfileFormat {
|
||||
std::vector<std::string> tsv;
|
||||
std::vector<std::string> tsm;
|
||||
std::vector<std::string> tsa;
|
||||
std::vector<std::string> tsp;
|
||||
std::vector<std::string> tsk;
|
||||
std::vector<std::string> tst;
|
||||
std::vector<std::string> tsc;
|
||||
std::vector<std::string> tsn;
|
||||
};
|
||||
|
||||
testProfileFormat buildTestProfile1() {
|
||||
testProfileFormat tp1;
|
||||
tp1.tsv.push_back("#Version");
|
||||
tp1.tsv.push_back("123.4");
|
||||
tp1.tsm.push_back("#Module");
|
||||
tp1.tsm.push_back("globebrowsing\t\t");
|
||||
tp1.tsm.push_back("gaia\tprint(\"success.\")\t");
|
||||
tp1.tsm.push_back("volume\t\tquit");
|
||||
tp1.tsa.push_back("#Asset");
|
||||
tp1.tsa.push_back("scene/solarsystem/planets/earth/moon/moon\trequired");
|
||||
tp1.tsa.push_back("scene/solarsystem/missions/apollo/apollo8\trequested");
|
||||
tp1.tsa.push_back("scene/solarsystem/planets/earth/earth\t");
|
||||
tp1.tsp.push_back("#Property");
|
||||
tp1.tsp.push_back("setPropertyValue\tNavigationHandler.OrbitalNavigator.FollowAnchorNodeRotationDistance\t20.000000");
|
||||
tp1.tsp.push_back("setPropertyValueSingle\tScene.Pluto.Renderable.Enabled\tfalse");
|
||||
tp1.tsp.push_back("setPropertyValue\tScene.Charon.Renderable.Enabled\tfalse");
|
||||
tp1.tsp.push_back("setPropertyValueSingle\tScene.PlutoBarycenterTrail.Renderable.Enabled\tfalse");
|
||||
tp1.tsk.push_back("#Keybinding");
|
||||
tp1.tsk.push_back("F8\tSets the time to the approach at Bennu.\tSet Bennu approach time\t/Missions/Osiris Rex\tfalse\t\"openspace.printInfo('Set time: Approach'); openspace.time.setTime('2018-SEP-11 21:31:01.183')\"");
|
||||
tp1.tsk.push_back("F9\tSets the time to the preliminary survey of Bennu.\tSet Bennu survey time\t/Missions/Osiris Rex\tfalse\t\"openspace.printInfo('Set time: Preliminary Survey'); openspace.time.setTime('2018-NOV-20 01:13:12.183')\"");
|
||||
tp1.tsk.push_back("F10\tSets the time to the orbital B event.\tSet orbital B event time\t/Missions/Osiris Rex\tfalse\t\"openspace.printInfo('Set time: Orbital B'); openspace.time.setTime('2019-APR-08 10:35:27.186')\"");
|
||||
tp1.tsk.push_back("F11\tSets the time to the recon event.\tSet recon event time\t/Missions/Osiris Rex\tfalse\t\"openspace.printInfo('Set time: Recon'); openspace.time.setTime('2019-MAY-25 03:50:31.195')\"");
|
||||
tp1.tst.push_back("#Time");
|
||||
tp1.tst.push_back("absolute\t1977-12-21T12:51:51.0");
|
||||
tp1.tsc.push_back("#Camera");
|
||||
tp1.tsc.push_back("setNavigationState\t\"NewHorizons\"\t\t\"Root\"\t-6.572656E1, -7.239404E1, -2.111890E1\t0.102164, -0.362945, 0.926193\t\t");
|
||||
tp1.tsn.push_back("#MarkNodes");
|
||||
tp1.tsn.push_back("Pluto");
|
||||
tp1.tsn.push_back("NewHorizons");
|
||||
tp1.tsn.push_back("Charon");
|
||||
|
||||
return tp1;
|
||||
}
|
||||
|
||||
std::string stringFromSingleProfileSection(std::vector<std::string>& section) {
|
||||
std::string result;
|
||||
for (std::string s : section) {
|
||||
result += s + "\n";
|
||||
}
|
||||
result += "\n";
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string stringFromTestProfileFormat(testProfileFormat& tpf) {
|
||||
std::string fullProfile;
|
||||
|
||||
fullProfile += stringFromSingleProfileSection(tpf.tsv);
|
||||
fullProfile += stringFromSingleProfileSection(tpf.tsm);
|
||||
fullProfile += stringFromSingleProfileSection(tpf.tsa);
|
||||
fullProfile += stringFromSingleProfileSection(tpf.tsp);
|
||||
fullProfile += stringFromSingleProfileSection(tpf.tsk);
|
||||
fullProfile += stringFromSingleProfileSection(tpf.tst);
|
||||
fullProfile += stringFromSingleProfileSection(tpf.tsc);
|
||||
fullProfile += stringFromSingleProfileSection(tpf.tsn);
|
||||
|
||||
return fullProfile;
|
||||
}
|
||||
|
||||
TEST_CASE("profileFile: Simple read and verify", "[profileFile]") {
|
||||
testProfileFormat test = buildTestProfile1();
|
||||
std::string testFull_string = stringFromTestProfileFormat(test);
|
||||
std::istringstream iss(testFull_string);
|
||||
|
||||
ProfileFile pf;
|
||||
pf.readLines([&iss](std::string& line) {
|
||||
if (getline(iss, line))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
|
||||
std::vector<std::string> tVect;
|
||||
|
||||
REQUIRE(pf.getVersion() == test.tsv[1]);
|
||||
REQUIRE(pf.time() == test.tst[1]);
|
||||
REQUIRE(pf.camera() == test.tsc[1]);
|
||||
tVect = pf.modules();
|
||||
REQUIRE(tVect[0] == test.tsm[1]);
|
||||
REQUIRE(tVect[1] == test.tsm[2]);
|
||||
REQUIRE(tVect[2] == test.tsm[3]);
|
||||
tVect = pf.assets();
|
||||
REQUIRE(tVect[0] == test.tsa[1]);
|
||||
REQUIRE(tVect[1] == test.tsa[2]);
|
||||
REQUIRE(tVect[2] == test.tsa[3]);
|
||||
tVect = pf.properties();
|
||||
REQUIRE(tVect[0] == test.tsp[1]);
|
||||
REQUIRE(tVect[1] == test.tsp[2]);
|
||||
REQUIRE(tVect[2] == test.tsp[3]);
|
||||
REQUIRE(tVect[3] == test.tsp[4]);
|
||||
tVect = pf.keybindings();
|
||||
REQUIRE(tVect[0] == test.tsk[1]);
|
||||
REQUIRE(tVect[1] == test.tsk[2]);
|
||||
REQUIRE(tVect[2] == test.tsk[3]);
|
||||
REQUIRE(tVect[3] == test.tsk[4]);
|
||||
tVect = pf.markNodes();
|
||||
REQUIRE(tVect[0] == test.tsn[1]);
|
||||
REQUIRE(tVect[1] == test.tsn[2]);
|
||||
REQUIRE(tVect[2] == test.tsn[3]);
|
||||
}
|
||||
|
||||
TEST_CASE("profileFile: Unrecognized header", "[profileFile]") {
|
||||
testProfileFormat test = buildTestProfile1();
|
||||
|
||||
test.tsa[0] = "#Azzet";
|
||||
std::string testFull_string = stringFromTestProfileFormat(test);
|
||||
std::istringstream iss(testFull_string);
|
||||
|
||||
ProfileFile pf;
|
||||
REQUIRE_THROWS_WITH(
|
||||
pf.readLines([&iss](std::string& line) {
|
||||
if (getline(iss, line))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
),
|
||||
Catch::Matchers::Contains ( "Invalid section header" )
|
||||
&& Catch::Matchers::Contains( "#Azzet" )
|
||||
);
|
||||
}
|
||||
|
||||
TEST_CASE("profileFile: Bad number of fields", "[profileFile]") {
|
||||
testProfileFormat test = buildTestProfile1();
|
||||
std::string testFull_string;
|
||||
test.tsm[1] = "globebrowsing\t\t\t";
|
||||
testFull_string = stringFromTestProfileFormat(test);
|
||||
{
|
||||
std::istringstream iss(testFull_string);
|
||||
ProfileFile pf;
|
||||
REQUIRE_THROWS_WITH(
|
||||
pf.readLines([&iss](std::string& line) {
|
||||
if (getline(iss, line))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
),
|
||||
Catch::Matchers::Contains ("fields required in a Module entry")
|
||||
);
|
||||
}
|
||||
|
||||
test.tsm[1] = "globebrowsing\t\t";
|
||||
test.tsc[1] = "setNavigationState\t\"NewHorizons\"\t\"Root\"\t-6.572656E1, -7.239404E1, -2.111890E1\t0.102164, -0.362945, 0.926193\t\t";
|
||||
testFull_string = stringFromTestProfileFormat(test);
|
||||
{
|
||||
std::istringstream iss(testFull_string);
|
||||
ProfileFile pf;
|
||||
REQUIRE_THROWS_WITH(
|
||||
pf.readLines([&iss](std::string& line) {
|
||||
if (getline(iss, line))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
),
|
||||
Catch::Matchers::Contains ("fields required in Camera entry")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("profileFile: Too many lines in time entry", "[profileFile]") {
|
||||
testProfileFormat test = buildTestProfile1();
|
||||
std::string testFull_string;
|
||||
test.tst.push_back("relative\t\"-1 day\"");
|
||||
testFull_string = stringFromTestProfileFormat(test);
|
||||
{
|
||||
std::istringstream iss(testFull_string);
|
||||
ProfileFile pf;
|
||||
REQUIRE_THROWS_WITH(
|
||||
pf.readLines([&iss](std::string& line) {
|
||||
if (getline(iss, line))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
),
|
||||
Catch::Matchers::Contains ("Too many lines in time section")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("profileFile: Required field missing", "[profileFile]") {
|
||||
testProfileFormat test = buildTestProfile1();
|
||||
std::string testFull_string;
|
||||
test.tsc[1] = "setNavigationState\t\"NewHorizons\"\ttest\t\"Root\"\t\t0.102164, -0.362945, 0.926193\t\t";
|
||||
|
||||
testFull_string = stringFromTestProfileFormat(test);
|
||||
{
|
||||
std::istringstream iss(testFull_string);
|
||||
ProfileFile pf;
|
||||
REQUIRE_THROWS_WITH(
|
||||
pf.readLines([&iss](std::string& line) {
|
||||
if (getline(iss, line))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
),
|
||||
Catch::Matchers::Contains ("Camera navigation setNavigationState position vector(arg 4/8) is required")
|
||||
);
|
||||
}
|
||||
|
||||
test.tsc[1] = "setNavigationState\t\"NewHorizons\"\t\t\"Root\"\t1, 2, 3\t0.102164, -0.362945, 0.926193\t\t";
|
||||
test.tsk[3] = "F10\tSets the time to the orbital B event.\tSet orbital B event time\t/Missions/Osiris Rex\t\t\"openspace.printInfo('Set time: Orbital B'); openspace.time.setTime('2019-APR-08 10:35:27.186')\"";
|
||||
testFull_string = stringFromTestProfileFormat(test);
|
||||
{
|
||||
std::istringstream iss(testFull_string);
|
||||
ProfileFile pf;
|
||||
REQUIRE_THROWS_WITH(
|
||||
pf.readLines([&iss](std::string& line) {
|
||||
if (getline(iss, line))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
),
|
||||
Catch::Matchers::Contains ("Keybinding local(T/F)(arg 4/6) is required")
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user