From 3d96836ee1eb310790a3f1b9285eb6a67aa2fb01 Mon Sep 17 00:00:00 2001 From: GPayne Date: Tue, 7 Apr 2020 20:39:31 -0600 Subject: [PATCH] Added unit tests for conversion from profile to scene --- include/openspace/scene/profile.h | 5 + include/openspace/scene/profilefile.h | 117 ++++++- src/scene/profile.cpp | 30 +- src/scene/profilefile.cpp | 24 +- tests/CMakeLists.txt | 2 + tests/profile/test_common.cpp | 124 ++++++++ tests/profile/test_common.h | 437 ++++++++++++++++++++++++++ tests/profile/test_profile.cpp | 79 +++++ tests/profile/test_profilefile.cpp | 74 +---- 9 files changed, 795 insertions(+), 97 deletions(-) create mode 100644 tests/profile/test_common.cpp create mode 100644 tests/profile/test_common.h create mode 100644 tests/profile/test_profile.cpp diff --git a/include/openspace/scene/profile.h b/include/openspace/scene/profile.h index e34e5ef111..42e1e2b3fd 100644 --- a/include/openspace/scene/profile.h +++ b/include/openspace/scene/profile.h @@ -47,6 +47,11 @@ namespace scripting { struct LuaLibrary; } class Profile { public: + /** + * Saves all current settings, starting from the profile that was loaded at startup, + * and all of the property & asset changes that were made since startup. + * \param filename The filename of the new profile to be saved + */ void saveCurrentSettingsToProfile(std::string filename); /** diff --git a/include/openspace/scene/profilefile.h b/include/openspace/scene/profilefile.h index f7f8c12593..730c3cda18 100644 --- a/include/openspace/scene/profilefile.h +++ b/include/openspace/scene/profilefile.h @@ -126,26 +126,123 @@ public: * form. * \param filename The filename to write to. */ - void writeToFile(std::string filename); + void writeToFile(const std::string filename); - //Methods for updating contents - void updateTime(); - void updateCamera(); - void addModuleLine(std::string line); - void addAssetLine(std::string line); - void addPropertyLine(std::string line); - void addKeybindingLine(std::string line); - void addMarkNodesLine(std::string line); + /** + * Updates the full string that defines the starting time. The format for this line + * is defined by ProfileFile::parseTime and Profile::convertToAsset_time + * \param line The time entry line to replace current time entry + */ + void updateTime(const std::string line); - //Methods for getting contents of each section + /** + * Updates the full string that defines the starting camera position. The format for + * this line is defined by ProfileFile::parseCamera and Profile::convertToAsset_camera + * \param line The camera entry line to replace current camera entry + */ + void updateCamera(const std::string line); + + /** + * Adds a new module line to the list of module lines to be analyzed by the profile + * at startup. The format for a module line is defined by ProfileFile::parseModule and + * Profile::convertToAsset_modules + * \param line The module name to be added + */ + void addModuleLine(const std::string line); + + /** + * Adds a new asset to the list of assets to be loaded at startup. The format for an + * asset line is defined by ProfileFile::parseAsset and Profile::convertToAsset_assets + * \param line The asset name to be added + */ + void addAssetLine(const std::string line); + + /** + * Adds a new property set command to the list of property settings to be + * performed at startup. The format for a property set command line is defined by + * ProfileFile::parseProperty and Profile::convertToAsset_properties + * \param line The property set command to be added + */ + void addPropertyLine(const std::string line); + + /** + * Adds a new keybinding shortcut to the list of keybindings. The format for a + * keybinding line is defined by ProfileFile::parseKeybinding and + * Profile::convertToAsset_keybindings + * \param line The keyboard shortcut line to be added + */ + void addKeybindingLine(const std::string line); + + /** + * Adds a new scenegraph node name to be added to the list of those marked as + * 'interesting'. The format for a mark nodes line is defined by + * ProfileFile::parseMarkNodes and Profile::convertToAsset_markNodes + * \param line The scenegraph node to be added + */ + void addMarkNodesLine(const std::string line); + + /** + * Returns the version number (profiles syntax version) string + * \return The version string + */ const std::string getVersion() const; + + /** + * Returns the profile's time string. See updateTime comment header for notes on + * syntax of this time string + * \return The time string + */ std::string time() const; + + /** + * Returns the profile's camera string. See updateCamera comment header for notes on + * syntax of this camera string + * \return The camera string + */ std::string camera() const; + + /** + * Returns the vector of OpenSpace modules listed in this profile. See addModuleLine + * comment header for notes on the syntax of each entry. + * \return The vector of module lines + */ std::vector modules() const; + + /** + * Returns the vector of OpenSpace assets listed in this profile. See addAssetLine + * comment header for notes on the syntax of each entry. + * \return The vector of asset lines + */ std::vector assets() const; + + /** + * Returns the vector of OpenSpace property set commands included in this profile. + * See addPropertyLine comment header for notes on the syntax of each entry. + * \return The vector of property set commands + */ std::vector properties() const; + + /** + * Returns the vector of OpenSpace keybinding shortcut definitions included in this + * profile. See addKeybindingLine comment header for syntax notes of each entry. + * \return The vector of keybinding shortcut definitions + */ std::vector keybindings() const; + + /** + * Returns the vector of OpenSpace scenegraph nodes marked as 'interesting'. + * See addMarkNodesLine comment header for syntax notes of each entry. + * \return The vector of nodes to be marked as interesting. + */ std::vector markNodes() const; + + /** + * Splits a tab-delimited line (of any type) into a vector with individual string + * entries. + * \param line The tab-delimited line from which to extract the fields + * \param result A vector of n strings that is populated by the split operation + * \return The number of fields that were extracted + */ size_t splitByTab(std::string line, std::vector& result); private: diff --git a/src/scene/profile.cpp b/src/scene/profile.cpp index a5df683edc..b8af9a5bd6 100644 --- a/src/scene/profile.cpp +++ b/src/scene/profile.cpp @@ -67,11 +67,12 @@ std::string Profile::convertToAsset(ProfileFile& pf) { result += convertToAsset_modules(pf) + "\n"; result += convertToAsset_assets(pf) + "\n"; + result += convertToAsset_keybindings(pf) + "\n"; result += "asset.onInitialize(function ()\n"; result += convertToAsset_time(pf) + "\n"; - result += convertToAsset_keybindings(pf) + "\n"; - result += convertToAsset_markNodes(pf); - result += convertToAsset_properties(pf); + result += " sceneHelper.bindKeys(Keybindings)\n\n"; + result += convertToAsset_markNodes(pf) + "\n"; + result += convertToAsset_properties(pf) + "\n"; result += convertToAsset_camera(pf); result += "end)\n"; @@ -107,10 +108,10 @@ std::string Profile::convertToAsset_assets(ProfileFile& pf) { std::string assetR; result += "asset.require(\"base\");\n"; - result += "'local assetHelper = asset.require(\"util/asset_helper\")\n"; - result += "'local propertyHelper = asset.require(\"util/property_helper\")\n"; - result += "'local sceneHelper = asset.require(\"util/scene_helper\")\n"; - result += "'local renderableHelper = asset.require(\"util/renderable_helper\")\n"; + result += "local assetHelper = asset.require(\"util/asset_helper\")\n"; + result += "local propertyHelper = asset.require(\"util/property_helper\")\n"; + result += "local sceneHelper = asset.require(\"util/scene_helper\")\n"; + result += "local renderableHelper = asset.require(\"util/renderable_helper\")\n"; for (size_t i = 0; i < pf.assets().size(); ++i) { std::string a = pf.assets()[i]; @@ -122,6 +123,9 @@ std::string Profile::convertToAsset_assets(ProfileFile& pf) { else if (fields[assetFieldReqd] == "requested") { assetR = "request"; } + else if (fields[assetFieldReqd] == "") { + assetR = "require"; + } else { std::string err = "Asset " + std::to_string(i + 1) + " of "; err += std::to_string(pf.assets().size()) + " has bad arg 2/2 which must "; @@ -150,7 +154,7 @@ std::string Profile::convertToAsset_properties(ProfileFile& pf) { throw ghoul::RuntimeError(err); } else { - result = " openspace." + fields[propertyFieldType] + "(\"" + result += " openspace." + fields[propertyFieldType] + "(\"" + fields[propertyFieldName] + "\", " + fields[propertyFieldValue] + ")\n"; } } @@ -174,7 +178,7 @@ std::string Profile::convertToAsset_keybindings(ProfileFile& pf) { result += " GuiPath = \"" + fields[3] + "\",\n"; result += " Local = " + fields[4] + ",\n"; result += " Command = " + fields[5] + "\n"; - result += " }\n"; + result += " },\n"; } result += "}\n"; return result; @@ -184,7 +188,7 @@ std::string Profile::convertToAsset_markNodes(ProfileFile& pf) { std::string result; if (pf.markNodes().size() > 0) { - result += " openspace.markInterestingNodes({'"; + result += " openspace.markInterestingNodes({"; } for (std::string m : pf.markNodes()) { result += "\"" + m + "\", "; @@ -223,7 +227,7 @@ std::string Profile::convertToAsset_camera(ProfileFile& pf) { pf.splitByTab(pf.camera(), fields); if (fields[cameraFieldType] == "setNavigationState") { - result += " openspace.navigation.setNavigationState({ "; + result += " openspace.navigation.setNavigationState({"; result += "Anchor = " + fields[cameraNavigationFieldAnchor] + ", "; if (fields[cameraNavigationFieldAim] != "") { result += "Aim = " + fields[cameraNavigationFieldAim] + ", "; @@ -231,9 +235,9 @@ std::string Profile::convertToAsset_camera(ProfileFile& pf) { if (fields[cameraNavigationFieldRef] != "") { result += "ReferenceFrame = " + fields[cameraNavigationFieldRef] + ", "; } - result += "Position = " + fields[cameraNavigationFieldPosition] + ", "; + result += "Position = {" + fields[cameraNavigationFieldPosition] + "}, "; if (fields[cameraNavigationFieldUp] != "") { - result += "Up = {" + fields[cameraNavigationFieldPosition] + "}, "; + result += "Up = {" + fields[cameraNavigationFieldUp] + "}, "; } if (fields[cameraNavigationFieldYaw] != "") { result += "Yaw = " + fields[cameraNavigationFieldYaw] + ", "; diff --git a/src/scene/profilefile.cpp b/src/scene/profilefile.cpp index 3ea55f17a5..b2c4251cb4 100644 --- a/src/scene/profilefile.cpp +++ b/src/scene/profilefile.cpp @@ -106,7 +106,7 @@ void ProfileFile::processIndividualLine(bool& insideSection, std::string line) { } } -void ProfileFile::writeToFile(std::string filename) { +void ProfileFile::writeToFile(const std::string filename) { std::ofstream outFile; try { outFile.open(filename, std::ofstream::out | std::ofstream::app); @@ -450,4 +450,26 @@ size_t ProfileFile::splitByTab(std::string line, std::vector& resul return result.size(); } +void ProfileFile::updateTime(const std::string line) { + _time = line; +} +void ProfileFile::updateCamera(const std::string line) { + _camera = line; +} +void ProfileFile::addModuleLine(const std::string line) { + _modules.push_back(line); +} +void ProfileFile::addAssetLine(const std::string line) { + _assets.push_back(line); +} +void ProfileFile::addPropertyLine(const std::string line) { + _properties.push_back(line); +} +void ProfileFile::addKeybindingLine(const std::string line) { + _keybindings.push_back(line); +} +void ProfileFile::addMarkNodesLine(const std::string line) { + _markNodes.push_back(line); +} + } // namespace openspace diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 018bc93ba6..75e310568c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -34,7 +34,9 @@ add_executable( test_lrucache.cpp test_luaconversions.cpp test_optionproperty.cpp + profile/test_common.cpp profile/test_profilefile.cpp + profile/test_profile.cpp test_rawvolumeio.cpp test_scriptscheduler.cpp test_spicemanager.cpp diff --git a/tests/profile/test_common.cpp b/tests/profile/test_common.cpp new file mode 100644 index 0000000000..dd8009c6a4 --- /dev/null +++ b/tests/profile/test_common.cpp @@ -0,0 +1,124 @@ +/***************************************************************************************** + * * + * 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 "test_common.h" + +#include "openspace/scene/profile.h" +#include "openspace/scene/profilefile.h" +#include +#include +#include +#include + +using namespace openspace; + +namespace { +} + +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& section, + bool blankLineSeparator) +{ + std::string result; + for (std::string s : section) { + result += s + "\n"; + } + if (blankLineSeparator) { + result += "\n"; + } + return result; +} + +std::string stringFromTestProfileFormat(testProfileFormat& tpf) { + std::string fullProfile; + + fullProfile += stringFromSingleProfileSection(tpf.tsv, true); + fullProfile += stringFromSingleProfileSection(tpf.tsm, true); + fullProfile += stringFromSingleProfileSection(tpf.tsa, true); + fullProfile += stringFromSingleProfileSection(tpf.tsp, true); + fullProfile += stringFromSingleProfileSection(tpf.tsk, true); + fullProfile += stringFromSingleProfileSection(tpf.tst, true); + fullProfile += stringFromSingleProfileSection(tpf.tsc, true); + fullProfile += stringFromSingleProfileSection(tpf.tsn, false); + + return fullProfile; +} + +ProfileFile makeProfileFromString(std::string s) { + std::istringstream iss(s); + + ProfileFile pf; + pf.readLines([&iss](std::string& line) { + if (getline(iss, line)) + return true; + else + return false; + }); + + return pf; +} + +StringPerLineReader::StringPerLineReader(std::string s) : _iss(s) { +} + +bool StringPerLineReader::getNextLine(std::string& line) { + if (getline(_iss, line)) + return true; + else + return false; +} diff --git a/tests/profile/test_common.h b/tests/profile/test_common.h new file mode 100644 index 0000000000..cdff281d0c --- /dev/null +++ b/tests/profile/test_common.h @@ -0,0 +1,437 @@ +/***************************************************************************************** + * * + * 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. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_TEST___PROFILE_COMMON___H__ +#define __OPENSPACE_TEST___PROFILE_COMMON___H__ + +#include "catch2/catch.hpp" +#include "openspace/scene/profile.h" +#include "openspace/scene/profilefile.h" +#include +#include +#include +#include + +using namespace openspace; + +namespace { +} + +struct testProfileFormat { + std::vector tsv; + std::vector tsm; + std::vector tsa; + std::vector tsp; + std::vector tsk; + std::vector tst; + std::vector tsc; + std::vector tsn; +}; + +const std::string newHorizonsProfileInput ="\ +#Version\n\ +1.0\n\ +\n\ +#Asset\n\ +scene/solarsystem/missions/newhorizons/newhorizons\trequired\n\ +scene/solarsystem/missions/newhorizons/model\trequired\n\ +\n\ +#Property\n\ +setPropertyValueSingle\tNavigationHandler.OrbitalNavigator.FollowAnchorNodeRotationDistance\t20.000000\n\ +setPropertyValueSingle\tScene.Pluto.Renderable.Enabled\tfalse\n\ +setPropertyValueSingle\tScene.Charon.Renderable.Enabled\tfalse\n\ +setPropertyValueSingle\tScene.PlutoBarycenterTrail.Renderable.Enabled\tfalse\n\ +\n\ +#Keybinding\n\ +a\tSets the focus of the camera on 'NewHorizons'.\tFocus on New Horizons\t/New Horizons\tfalse\t\"openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'NewHorizons');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', '');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)\"\n\ +SHIFT+a\tSets the focus of the camera on 'NewHorizons'.\tAnchor at New Horizons, Aim at Pluto\t/New Horizons\tfalse\t\"openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'NewHorizons');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', 'Pluto');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)\"\n\ +s\tSets the focus of the camera on 'Pluto'\tFocus on Pluto\t/New Horizons\tfalse\t\"openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Pluto') ;openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', ''); openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)\"\n\ +d\tSets the focus of the camera on 'Charon'.\tFocus on New Charon\t/New Horizons\tfalse\t\"openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Charon');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', '');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)\"\n\ +F7\tToggles New Horizons image projection.\tToggle NH Image Projection\t/New Horizons\tfalse\t[[local enabled = openspace.getPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.PerformProjection'); openspace.setPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.PerformProjection', not enabled); openspace.setPropertyValue('Scene.CharonProjection.Renderable.ProjectionComponent.PerformProjection', not enabled)]]\n\ +F8\tRemoves all image projections from Pluto and Charon.\tClear image projections\t/New Horizons\tfalse\t\"openspace.setPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.ClearAllProjections', true); openspace.setPropertyValue('Scene.CharonProjection.Renderable.ProjectionComponent.ClearAllProjections', true)\"\n\ +F9\tJumps to the 14th of July 2015 at 0900 UTC and clears all projections.\tReset time and projections\t/New Horizons\tfalse\t\"openspace.time.setTime('2015-07-14T09:00:00.00');openspace.setPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.ClearAllProjections', true);openspace.setPropertyValue('Scene.CharonProjection.Renderable.ProjectionComponent.ClearAllProjections', true)\"\n\ +KP_8\tIncreases the height map exaggeration on Pluto.\tPluto HeightExaggeration +\t/New Horizons\tfalse\tpropertyHelper.increment('Scene.PlutoProjection.Renderable.HeightExaggeration', 5000)\n\ +CTRL+I\tIncreases the height map exaggeration on Pluto.\tPluto HeightExaggeration +\t/New Horizons\tfalse\tpropertyHelper.increment('Scene.PlutoProjection.Renderable.HeightExaggeration', 5000)\n\ +KP_2\tDecreases the height map exaggeration on Pluto.\tPluto HeightExaggeration -\t/New Horizons\tfalse\tpropertyHelper.decrement('Scene.PlutoProjection.Renderable.HeightExaggeration', 5000)\n\ +CTRL+K\tDecreases the height map exaggeration on Pluto.\tPluto HeightExaggeration -\t/New Horizons\tfalse\tpropertyHelper.decrement('Scene.PlutoProjection.Renderable.HeightExaggeration', 5000)\n\ +KP_9\tIncreases the height map exaggeration on Charon.\tCharon HeightExaggeration +\t/New Horizons\tfalse\tpropertyHelper.increment('Scene.CharonProjection.Renderable.HeightExaggeration', 5000)\n\ +CTRL+O\tIncreases the height map exaggeration on Charon.\tCharon HeightExaggeration +\t/New Horizons\tfalse\tpropertyHelper.increment('Scene.CharonProjection.Renderable.HeightExaggeration', 5000)\n\ +KP_3\tDecreases the height map exaggeration on Charon.\tCharon HeightExaggeration -\t/New Horizons\tfalse\tpropertyHelper.decrement('Scene.CharonProjection.Renderable.HeightExaggeration', 5000)\n\ +CTRL+L\tDecreases the height map exaggeration on Charon.\tCharon HeightExaggeration -\t/New Horizons\tfalse\tpropertyHelper.decrement('Scene.CharonProjection.Renderable.HeightExaggeration', 5000)\n\ +o\tToggles the visibility of the trail behind Pluto.\tToggle Pluto Trail\t/New Horizons\tfalse\tpropertyHelper.invert('Scene.PlutoBarycentricTrail.Renderable.Enabled')\n\ +j\tToggles the visibility of the text labels of Pluto, Charon, Hydra, Nix, Kerberos, and Styx.\tToggle Pluto Labels\t/New Horizons\tfalse\trenderableHelper.toggle('Scene.PlutoText') .. renderableHelper.toggle('Scene.CharonText') .. renderableHelper.toggle('Scene.HydraText') .. renderableHelper.toggle('Scene.NixText') .. renderableHelper.toggle('Scene.KerberosText') .. renderableHelper.toggle('Scene.StyxText')\n\ +l\tToggles the visibility of the labels for the New Horizons instruments.\tToggle New Horizons Labels\t/New Horizons\tfalse\tpropertyHelper.fadeInOut('Scene.Labels.Renderable.Opacity', 2.0)\n\ +m\tDraws the instrument field of views in a solid color or as lines.\tToggle instrument FOVs\t/New Horizons\tfalse\tpropertyHelper.invert('Scene.NH_LORRI.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_LEISA.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_PAN1.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_PAN2.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_RED.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_BLUE.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_FT.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_METHANE.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_NIR.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_ALICE_AIRGLOW.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_ALICE_SOC.Renderable.SolidDraw')\n\ +Shift+t\tToggles the visibility of the shadow visualization of Pluto and Charon.\tToggle Shadows\t/New Horizons\tfalse\trenderableHelper.toggle('Scene.PlutoShadow') .. renderableHelper.toggle('Scene.CharonShadow')\n\ +t\tToggles the trail of New Horizons.\tToggle NH Trail\t/New Horizons\tfalse\trenderableHelper.toggle('Scene.NewHorizonsTrailPluto')\n\ +h\tDisables visibility of the trails\tHide Trails\t/Rendering\tfalse\t\"local list = openspace.getProperty('*Trail.Renderable.Enabled'); for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end\"\n\ +1\tSetting the simulation speed to 1 seconds per realtime second\tSet sim speed 1\t/Simulation Speed\tfalse\t\"openspace.time.interpolateDeltaTime(1)\"\n\ +2\tSetting the simulation speed to 5 seconds per realtime second\tSet sim speed 5\t/Simulation Speed\tfalse\t\"openspace.time.interpolateDeltaTime(5)\"\n\ +3\tSetting the simulation speed to 10 seconds per realtime second\tSet sim speed 10\t/Simulation Speed\tfalse\t\"openspace.time.interpolateDeltaTime(10)\"\n\ +4\tSetting the simulation speed to 20 seconds per realtime second\tSet sim speed 20\t/Simulation Speed\tfalse\t\"openspace.time.interpolateDeltaTime(20)\"\n\ +5\tSetting the simulation speed to 40 seconds per realtime second\tSet sim speed 40\t/Simulation Speed\tfalse\t\"openspace.time.interpolateDeltaTime(40)\"\n\ +6\tSetting the simulation speed to 60 seconds per realtime second\tSet sim speed 60\t/Simulation Speed\tfalse\t\"openspace.time.interpolateDeltaTime(60)\"\n\ +7\tSetting the simulation speed to 120 seconds per realtime second\tSet sim speed 120\t/Simulation Speed\tfalse\t\"openspace.time.interpolateDeltaTime(120)\"\n\ +8\tSetting the simulation speed to 360 seconds per realtime second\tSet sim speed 360\t/Simulation Speed\tfalse\t\"openspace.time.interpolateDeltaTime(360)\"\n\ +9\tSetting the simulation speed to 540 seconds per realtime second\tSet sim speed 540\t/Simulation Speed\tfalse\t\"openspace.time.interpolateDeltaTime(540)\"\n\ +0\tSetting the simulation speed to 1080 seconds per realtime second\tSet sim speed 1080\t/Simulation Speed\tfalse\t\"openspace.time.interpolateDeltaTime(1080)\"\n\ +Shift+1\tSetting the simulation speed to 2160 seconds per realtime second\tSet sim speed 2160\t/Simulation Speed\tfalse\t\"openspace.time.interpolateDeltaTime(2160)\"\n\ +Shift+2\tSetting the simulation speed to 4320 seconds per realtime second\tSet sim speed 4320\t/Simulation Speed\tfalse\t\"openspace.time.interpolateDeltaTime(4320)\"\n\ +Shift+3\tSetting the simulation speed to 8640 seconds per realtime second\tSet sim speed 8640\t/Simulation Speed\tfalse\t\"openspace.time.interpolateDeltaTime(8640)\"\n\ +\n\ +#Time\n\ +absolute\t2015-07-14T08:00:00.00\n\ +\n\ +#Camera\n\ +setNavigationState\t\"NewHorizons\"\t\t\"Root\"\t-6.572656E1, -7.239404E1, -2.111890E1\t0.102164, -0.362945, 0.926193\t\t\n\ +\n\ +#MarkNodes\n\ +Pluto\n\ +NewHorizons\n\ +Charon"; + +const std::string newHorizonsExpectedSceneOutput = "\ +\n\ +asset.require(\"base\");\n\ +local assetHelper = asset.require(\"util/asset_helper\")\n\ +local propertyHelper = asset.require(\"util/property_helper\")\n\ +local sceneHelper = asset.require(\"util/scene_helper\")\n\ +local renderableHelper = asset.require(\"util/renderable_helper\")\n\ +asset.require(\"scene/solarsystem/missions/newhorizons/newhorizons\")\n\ +asset.require(\"scene/solarsystem/missions/newhorizons/model\")\n\ +\n\ +local Keybindings = {\n\ + {\n\ + Key = \"a\",\n\ + Documentation = \"Sets the focus of the camera on 'NewHorizons'.\",\n\ + Name = \"Focus on New Horizons\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = \"openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'NewHorizons');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', '');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)\"\n\ + },\n\ + {\n\ + Key = \"SHIFT+a\",\n\ + Documentation = \"Sets the focus of the camera on 'NewHorizons'.\",\n\ + Name = \"Anchor at New Horizons, Aim at Pluto\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = \"openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'NewHorizons');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', 'Pluto');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)\"\n\ + },\n\ + {\n\ + Key = \"s\",\n\ + Documentation = \"Sets the focus of the camera on 'Pluto'\",\n\ + Name = \"Focus on Pluto\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = \"openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Pluto') ;openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', ''); openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)\"\n\ + },\n\ + {\n\ + Key = \"d\",\n\ + Documentation = \"Sets the focus of the camera on 'Charon'.\",\n\ + Name = \"Focus on New Charon\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = \"openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Charon');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', '');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)\"\n\ + },\n\ + {\n\ + Key = \"F7\",\n\ + Documentation = \"Toggles New Horizons image projection.\",\n\ + Name = \"Toggle NH Image Projection\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = [[local enabled = openspace.getPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.PerformProjection'); openspace.setPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.PerformProjection', not enabled); openspace.setPropertyValue('Scene.CharonProjection.Renderable.ProjectionComponent.PerformProjection', not enabled)]]\n\ + },\n\ + {\n\ + Key = \"F8\",\n\ + Documentation = \"Removes all image projections from Pluto and Charon.\",\n\ + Name = \"Clear image projections\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = \"openspace.setPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.ClearAllProjections', true); openspace.setPropertyValue('Scene.CharonProjection.Renderable.ProjectionComponent.ClearAllProjections', true)\"\n\ + },\n\ + {\n\ + Key = \"F9\",\n\ + Documentation = \"Jumps to the 14th of July 2015 at 0900 UTC and clears all projections.\",\n\ + Name = \"Reset time and projections\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = \"openspace.time.setTime('2015-07-14T09:00:00.00');openspace.setPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.ClearAllProjections', true);openspace.setPropertyValue('Scene.CharonProjection.Renderable.ProjectionComponent.ClearAllProjections', true)\"\n\ + },\n\ + {\n\ + Key = \"KP_8\",\n\ + Documentation = \"Increases the height map exaggeration on Pluto.\",\n\ + Name = \"Pluto HeightExaggeration +\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = propertyHelper.increment('Scene.PlutoProjection.Renderable.HeightExaggeration', 5000)\n\ + },\n\ + {\n\ + Key = \"CTRL+I\",\n\ + Documentation = \"Increases the height map exaggeration on Pluto.\",\n\ + Name = \"Pluto HeightExaggeration +\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = propertyHelper.increment('Scene.PlutoProjection.Renderable.HeightExaggeration', 5000)\n\ + },\n\ + {\n\ + Key = \"KP_2\",\n\ + Documentation = \"Decreases the height map exaggeration on Pluto.\",\n\ + Name = \"Pluto HeightExaggeration -\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = propertyHelper.decrement('Scene.PlutoProjection.Renderable.HeightExaggeration', 5000)\n\ + },\n\ + {\n\ + Key = \"CTRL+K\",\n\ + Documentation = \"Decreases the height map exaggeration on Pluto.\",\n\ + Name = \"Pluto HeightExaggeration -\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = propertyHelper.decrement('Scene.PlutoProjection.Renderable.HeightExaggeration', 5000)\n\ + },\n\ + {\n\ + Key = \"KP_9\",\n\ + Documentation = \"Increases the height map exaggeration on Charon.\",\n\ + Name = \"Charon HeightExaggeration +\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = propertyHelper.increment('Scene.CharonProjection.Renderable.HeightExaggeration', 5000)\n\ + },\n\ + {\n\ + Key = \"CTRL+O\",\n\ + Documentation = \"Increases the height map exaggeration on Charon.\",\n\ + Name = \"Charon HeightExaggeration +\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = propertyHelper.increment('Scene.CharonProjection.Renderable.HeightExaggeration', 5000)\n\ + },\n\ + {\n\ + Key = \"KP_3\",\n\ + Documentation = \"Decreases the height map exaggeration on Charon.\",\n\ + Name = \"Charon HeightExaggeration -\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = propertyHelper.decrement('Scene.CharonProjection.Renderable.HeightExaggeration', 5000)\n\ + },\n\ + {\n\ + Key = \"CTRL+L\",\n\ + Documentation = \"Decreases the height map exaggeration on Charon.\",\n\ + Name = \"Charon HeightExaggeration -\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = propertyHelper.decrement('Scene.CharonProjection.Renderable.HeightExaggeration', 5000)\n\ + },\n\ + {\n\ + Key = \"o\",\n\ + Documentation = \"Toggles the visibility of the trail behind Pluto.\",\n\ + Name = \"Toggle Pluto Trail\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = propertyHelper.invert('Scene.PlutoBarycentricTrail.Renderable.Enabled')\n\ + },\n\ + {\n\ + Key = \"j\",\n\ + Documentation = \"Toggles the visibility of the text labels of Pluto, Charon, Hydra, Nix, Kerberos, and Styx.\",\n\ + Name = \"Toggle Pluto Labels\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = renderableHelper.toggle('Scene.PlutoText') .. renderableHelper.toggle('Scene.CharonText') .. renderableHelper.toggle('Scene.HydraText') .. renderableHelper.toggle('Scene.NixText') .. renderableHelper.toggle('Scene.KerberosText') .. renderableHelper.toggle('Scene.StyxText')\n\ + },\n\ + {\n\ + Key = \"l\",\n\ + Documentation = \"Toggles the visibility of the labels for the New Horizons instruments.\",\n\ + Name = \"Toggle New Horizons Labels\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = propertyHelper.fadeInOut('Scene.Labels.Renderable.Opacity', 2.0)\n\ + },\n\ + {\n\ + Key = \"m\",\n\ + Documentation = \"Draws the instrument field of views in a solid color or as lines.\",\n\ + Name = \"Toggle instrument FOVs\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = propertyHelper.invert('Scene.NH_LORRI.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_LEISA.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_PAN1.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_PAN2.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_RED.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_BLUE.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_FT.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_METHANE.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_NIR.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_ALICE_AIRGLOW.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_ALICE_SOC.Renderable.SolidDraw')\n\ + },\n\ + {\n\ + Key = \"Shift+t\",\n\ + Documentation = \"Toggles the visibility of the shadow visualization of Pluto and Charon.\",\n\ + Name = \"Toggle Shadows\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = renderableHelper.toggle('Scene.PlutoShadow') .. renderableHelper.toggle('Scene.CharonShadow')\n\ + },\n\ + {\n\ + Key = \"t\",\n\ + Documentation = \"Toggles the trail of New Horizons.\",\n\ + Name = \"Toggle NH Trail\",\n\ + GuiPath = \"/New Horizons\",\n\ + Local = false,\n\ + Command = renderableHelper.toggle('Scene.NewHorizonsTrailPluto')\n\ + },\n\ + {\n\ + Key = \"h\",\n\ + Documentation = \"Disables visibility of the trails\",\n\ + Name = \"Hide Trails\",\n\ + GuiPath = \"/Rendering\",\n\ + Local = false,\n\ + Command = \"local list = openspace.getProperty('*Trail.Renderable.Enabled'); for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end\"\n\ + },\n\ + {\n\ + Key = \"1\",\n\ + Documentation = \"Setting the simulation speed to 1 seconds per realtime second\",\n\ + Name = \"Set sim speed 1\",\n\ + GuiPath = \"/Simulation Speed\",\n\ + Local = false,\n\ + Command = \"openspace.time.interpolateDeltaTime(1)\"\n\ + },\n\ + {\n\ + Key = \"2\",\n\ + Documentation = \"Setting the simulation speed to 5 seconds per realtime second\",\n\ + Name = \"Set sim speed 5\",\n\ + GuiPath = \"/Simulation Speed\",\n\ + Local = false,\n\ + Command = \"openspace.time.interpolateDeltaTime(5)\"\n\ + },\n\ + {\n\ + Key = \"3\",\n\ + Documentation = \"Setting the simulation speed to 10 seconds per realtime second\",\n\ + Name = \"Set sim speed 10\",\n\ + GuiPath = \"/Simulation Speed\",\n\ + Local = false,\n\ + Command = \"openspace.time.interpolateDeltaTime(10)\"\n\ + },\n\ + {\n\ + Key = \"4\",\n\ + Documentation = \"Setting the simulation speed to 20 seconds per realtime second\",\n\ + Name = \"Set sim speed 20\",\n\ + GuiPath = \"/Simulation Speed\",\n\ + Local = false,\n\ + Command = \"openspace.time.interpolateDeltaTime(20)\"\n\ + },\n\ + {\n\ + Key = \"5\",\n\ + Documentation = \"Setting the simulation speed to 40 seconds per realtime second\",\n\ + Name = \"Set sim speed 40\",\n\ + GuiPath = \"/Simulation Speed\",\n\ + Local = false,\n\ + Command = \"openspace.time.interpolateDeltaTime(40)\"\n\ + },\n\ + {\n\ + Key = \"6\",\n\ + Documentation = \"Setting the simulation speed to 60 seconds per realtime second\",\n\ + Name = \"Set sim speed 60\",\n\ + GuiPath = \"/Simulation Speed\",\n\ + Local = false,\n\ + Command = \"openspace.time.interpolateDeltaTime(60)\"\n\ + },\n\ + {\n\ + Key = \"7\",\n\ + Documentation = \"Setting the simulation speed to 120 seconds per realtime second\",\n\ + Name = \"Set sim speed 120\",\n\ + GuiPath = \"/Simulation Speed\",\n\ + Local = false,\n\ + Command = \"openspace.time.interpolateDeltaTime(120)\"\n\ + },\n\ + {\n\ + Key = \"8\",\n\ + Documentation = \"Setting the simulation speed to 360 seconds per realtime second\",\n\ + Name = \"Set sim speed 360\",\n\ + GuiPath = \"/Simulation Speed\",\n\ + Local = false,\n\ + Command = \"openspace.time.interpolateDeltaTime(360)\"\n\ + },\n\ + {\n\ + Key = \"9\",\n\ + Documentation = \"Setting the simulation speed to 540 seconds per realtime second\",\n\ + Name = \"Set sim speed 540\",\n\ + GuiPath = \"/Simulation Speed\",\n\ + Local = false,\n\ + Command = \"openspace.time.interpolateDeltaTime(540)\"\n\ + },\n\ + {\n\ + Key = \"0\",\n\ + Documentation = \"Setting the simulation speed to 1080 seconds per realtime second\",\n\ + Name = \"Set sim speed 1080\",\n\ + GuiPath = \"/Simulation Speed\",\n\ + Local = false,\n\ + Command = \"openspace.time.interpolateDeltaTime(1080)\"\n\ + },\n\ + {\n\ + Key = \"Shift+1\",\n\ + Documentation = \"Setting the simulation speed to 2160 seconds per realtime second\",\n\ + Name = \"Set sim speed 2160\",\n\ + GuiPath = \"/Simulation Speed\",\n\ + Local = false,\n\ + Command = \"openspace.time.interpolateDeltaTime(2160)\"\n\ + },\n\ + {\n\ + Key = \"Shift+2\",\n\ + Documentation = \"Setting the simulation speed to 4320 seconds per realtime second\",\n\ + Name = \"Set sim speed 4320\",\n\ + GuiPath = \"/Simulation Speed\",\n\ + Local = false,\n\ + Command = \"openspace.time.interpolateDeltaTime(4320)\"\n\ + },\n\ + {\n\ + Key = \"Shift+3\",\n\ + Documentation = \"Setting the simulation speed to 8640 seconds per realtime second\",\n\ + Name = \"Set sim speed 8640\",\n\ + GuiPath = \"/Simulation Speed\",\n\ + Local = false,\n\ + Command = \"openspace.time.interpolateDeltaTime(8640)\"\n\ + },\n\ +}\n\ +\n\ +asset.onInitialize(function ()\n\ + openspace.time.setTime(\"2015-07-14T08:00:00.00\")\n\ +\n\ + sceneHelper.bindKeys(Keybindings)\n\ +\n\ + openspace.markInterestingNodes({\"Pluto\", \"NewHorizons\", \"Charon\", })\n\ +\n\ + openspace.setPropertyValueSingle(\"NavigationHandler.OrbitalNavigator.FollowAnchorNodeRotationDistance\", 20.000000)\n\ + openspace.setPropertyValueSingle(\"Scene.Pluto.Renderable.Enabled\", false)\n\ + openspace.setPropertyValueSingle(\"Scene.Charon.Renderable.Enabled\", false)\n\ + openspace.setPropertyValueSingle(\"Scene.PlutoBarycenterTrail.Renderable.Enabled\", false)\n\ +\n\ + openspace.navigation.setNavigationState({Anchor = \"NewHorizons\", ReferenceFrame = \"Root\", Position = {-6.572656E1, -7.239404E1, -2.111890E1}, Up = {0.102164, -0.362945, 0.926193}, })\n\ +end)"; + +testProfileFormat buildTestProfile1(); +std::string stringFromSingleProfileSection(std::vector& section, + bool blankLineSeparator); +std::string stringFromTestProfileFormat(testProfileFormat& tpf); +ProfileFile makeProfileFromString(std::string s); + +class StringPerLineReader { +public: + StringPerLineReader(std::string s); + bool getNextLine(std::string& line); + +private: + std::istringstream _iss; +}; + +#endif //__OPENSPACE_TEST___PROFILE_COMMON___H__ diff --git a/tests/profile/test_profile.cpp b/tests/profile/test_profile.cpp new file mode 100644 index 0000000000..62389a275b --- /dev/null +++ b/tests/profile/test_profile.cpp @@ -0,0 +1,79 @@ +/***************************************************************************************** + * * + * 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 "test_common.h" + +#include "openspace/scene/profile.h" +#include +#include +#include +#include + +using namespace openspace; + +namespace { +} + +static void addLineHeaderForFailureMessage(std::string& s, size_t lineNumber) { + s = "@line " + std::to_string(lineNumber) + ": '" + s + "'"; +} + +TEST_CASE("profile: Convert profileFile to asset", "[profile]") { + testProfileFormat test = buildTestProfile1(); + std::string testFull_string = stringFromTestProfileFormat(test); + + ProfileFile pf = makeProfileFromString(testFull_string); + + Profile p; + REQUIRE_NOTHROW( + p.convertToAsset(pf) + ); +} + +TEST_CASE("profile: Verify conversion to scene", "[profile]") { + ProfileFile pf = makeProfileFromString(newHorizonsProfileInput); + + Profile p; + std::string result; + REQUIRE_NOTHROW( + result = p.convertToAsset(pf) + ); + + std::string testing, comparing; + StringPerLineReader sr_result(result); + StringPerLineReader sr_standard(newHorizonsExpectedSceneOutput); + + size_t lineN = 1; + while (sr_result.getNextLine(testing)) { + sr_standard.getNextLine(comparing); + addLineHeaderForFailureMessage(testing, lineN); + addLineHeaderForFailureMessage(comparing, lineN); + REQUIRE(testing == comparing); + lineN++; + } + //If this fails there are extra lines in the comparison string that weren't in result + REQUIRE(sr_standard.getNextLine(comparing) == false); +} + diff --git a/tests/profile/test_profilefile.cpp b/tests/profile/test_profilefile.cpp index fce123113e..ad1db7997d 100644 --- a/tests/profile/test_profilefile.cpp +++ b/tests/profile/test_profilefile.cpp @@ -25,6 +25,7 @@ #include "catch2/catch.hpp" #include "openspace/scene/profilefile.h" +#include "test_common.h" #include #include #include @@ -35,79 +36,6 @@ using namespace openspace; namespace { } -struct testProfileFormat { - std::vector tsv; - std::vector tsm; - std::vector tsa; - std::vector tsp; - std::vector tsk; - std::vector tst; - std::vector tsc; - std::vector 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& section, - bool blankLineSeparator) -{ - std::string result; - for (std::string s : section) { - result += s + "\n"; - } - if (blankLineSeparator) { - result += "\n"; - } - return result; -} - -std::string stringFromTestProfileFormat(testProfileFormat& tpf) { - std::string fullProfile; - - fullProfile += stringFromSingleProfileSection(tpf.tsv, true); - fullProfile += stringFromSingleProfileSection(tpf.tsm, true); - fullProfile += stringFromSingleProfileSection(tpf.tsa, true); - fullProfile += stringFromSingleProfileSection(tpf.tsp, true); - fullProfile += stringFromSingleProfileSection(tpf.tsk, true); - fullProfile += stringFromSingleProfileSection(tpf.tst, true); - fullProfile += stringFromSingleProfileSection(tpf.tsc, true); - fullProfile += stringFromSingleProfileSection(tpf.tsn, false); - - return fullProfile; -} - TEST_CASE("profileFile: Simple read and verify", "[profileFile]") { testProfileFormat test = buildTestProfile1(); std::string testFull_string = stringFromTestProfileFormat(test);