/***************************************************************************************** * * * OpenSpace * * * * Copyright (c) 2014-2023 * * * * 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 #include #include #include #include #include #include #include #include #include using namespace openspace::configuration; namespace { std::string stringify(const std::string filename) { std::ifstream myfile; myfile.open(filename); std::stringstream buffer; buffer << myfile.rdbuf(); return buffer.str(); } void attemptValidation(const std::string cfgString) { std::filesystem::path schemaDir = absPath("${TESTDIR}/../config/schema"); std::string schemaString = stringify( schemaDir.string() + "/sgcteditor.schema.json" ); sgct::validateConfigAgainstSchema(cfgString, schemaString, schemaDir); } } // namespace TEST_CASE("SgctEdit: pass", "[sgctedit]") { const std::string config = R"({ "generator": { "major": 1, "minor": 1, "name": "SgctWindowConfig" }, "masteraddress": "localhost", "nodes": [ { "address": "localhost", "port": 20401, "windows": [ { "border": true, "id": 0, "monitor": 0, "name": "ffss", "pos": { "x": 112, "y": 77 }, "size": { "x": 1280, "y": 720 }, "viewports": [ { "pos": { "x": 0.0, "y": 0.0 }, "projection": { "heightoffset": 0.0, "quality": "1024", "type": "CylindricalProjection" }, "size": { "x": 1.0, "y": 1.0 }, "tracked": true } ] } ] } ], "scene": { "orientation": { "w": 0.0, "x": 0.0, "y": 0.0, "z": 0.0 } }, "users": [ { "eyeseparation": 0.06499999761581421, "pos": { "x": 0.0, "y": 0.0, "z": 4.0 } } ], "version": 1 })"; CHECK_NOTHROW(attemptValidation(config)); } TEST_CASE("SgctEdit: addedTrailingBracket", "[sgctedit]") { const std::string config = R"({ "generator": { "major": 0, "minor": 1, "name": "SgctWindowConfig" }, "masteraddress": "localhost", "nodes": [ { "address": "localhost", "port": 20401, "windows": [ { "border": true, "id": 0, "monitor": 0, "name": "ffss", "pos": { "x": 112, "y": 77 }, "size": { "x": 1280, "y": 720 }, "viewports": [ { "pos": { "x": 0.0, "y": 0.0 }, "projection": { "heightoffset": 0.0, "quality": "1024", "type": "CylindricalProjection" }, "size": { "x": 1.0, "y": 1.0 }, "tracked": true } ] } ] } ], "scene": { "orientation": { "w": 0.0, "x": 0.0, "y": 0.0, "z": 0.0 } }, "users": [ { "eyeseparation": 0.06499999761581421, "pos": { "x": 0.0, "y": 0.0, "z": 4.0 } } ], "version": 1 }})"; CHECK_THROWS_MATCHES( attemptValidation(config), nlohmann::json::parse_error, Catch::Matchers::Message( "[json.exception.parse_error.101] parse error at line 67, column 2: " "syntax error while parsing value - unexpected '}'; expected " "end of input" ) ); } TEST_CASE("SgctEdit: missingMasterAddress", "[sgctedit]") { const std::string config = R"({ "generator": { "major": 1, "minor": 1, "name": "SgctWindowConfig" }, "nodes": [ { "address": "localhost", "port": 20401, "windows": [ { "border": true, "id": 0, "monitor": 1, "name": "name", "pos": { "x": 112, "y": 77 }, "size": { "x": 1280, "y": 720 }, "viewports": [ { "pos": { "x": 0.0, "y": 0.0 }, "projection": { "heightoffset": 0.0, "quality": "1024", "type": "CylindricalProjection" }, "size": { "x": 1.0, "y": 1.0 }, "tracked": true } ] } ] } ], "scene": { "orientation": { "w": 0.0, "x": 0.0, "y": 0.0, "z": 0.0 } }, "users": [ { "eyeseparation": 0.06499999761581421, "pos": { "x": 0.0, "y": 0.0, "z": 4.0 } } ], "version": 1 })"; CHECK_THROWS_MATCHES( attemptValidation(config), std::exception, Catch::Matchers::Message( "At of {\"generator\":{\"major\":1,\"minor\":1,\"name\":" "\"SgctWindowConfig\"},\"nodes\":[{\"address\":\"localhost\",\"port\":" "20401,\"windows\":[{\"border\":true,\"id\":0,\"monitor\":1,\"name\":" "\"name\",\"pos\":{\"x\":112,\"y\":77},\"size\":{\"x\":1280,\"y\":720}," "\"viewports\":[{\"pos\":{\"x\":0.0,\"y\":0.0},\"projection\":" "{\"heightoffset\":0.0,\"quality\":\"1024\",\"type\":" "\"CylindricalProjection\"},\"size\":{\"x\":1.0,\"y\":1.0},\"tracked\":" "true}]}]}],\"scene\":{\"orientation\":{\"w\":0.0,\"x\":0.0,\"y\":0.0," "\"z\":0.0}},\"users\":[{\"eyeseparation\":0.06499999761581421,\"pos\":" "{\"x\":0.0,\"y\":0.0,\"z\":4.0}}],\"version\":1} - required property " "'masteraddress' not found in object\n" ) ); } TEST_CASE("SgctEdit: missingPos", "[sgctedit]") { const std::string config = R"({ "generator": { "major": 1, "minor": 1, "name": "SgctWindowConfig" }, "masteraddress": "localhost", "nodes": [ { "address": "localhost", "port": 20401, "windows": [ { "border": true, "id": 0, "monitor": 0, "name": "name", "pos": { "x": 112, "y": 77 }, "size": { "x": 1280, "y": 720 }, "viewports": [ { "pos": { "x": 0.0, "y": 0.0 }, "projection": { "heightoffset": 0.0, "quality": "1024", "type": "CylindricalProjection" }, "size": { "x": 1.0, "y": 1.0 }, "tracked": true } ] } ] } ], "scene": { "orientation": { "w": 0.0, "x": 0.0, "y": 0.0, "z": 0.0 } }, "users": [ { "eyeseparation": 0.06499999761581421 } ], "version": 1 })"; CHECK_THROWS_MATCHES( attemptValidation(config), std::exception, Catch::Matchers::Message( "At /users/0 of {\"eyeseparation\":0.06499999761581421} - required " "property 'pos' not found in object\n" ) ); } TEST_CASE("SgctEdit: missingGenerator", "[sgctedit]") { const std::string config = R"({ "masteraddress": "localhost", "nodes": [ { "address": "localhost", "port": 20401, "windows": [ { "border": true, "id": 0, "monitor": 0, "name": "name", "pos": { "x": 112, "y": 77 }, "size": { "x": 1280, "y": 720 }, "viewports": [ { "pos": { "x": 0.0, "y": 0.0 }, "projection": { "heightoffset": 0.0, "quality": "1024", "type": "CylindricalProjection" }, "size": { "x": 1.0, "y": 1.0 }, "tracked": true } ] } ] } ], "scene": { "orientation": { "w": 0.0, "x": 0.0, "y": 0.0, "z": 0.0 } }, "users": [ { "eyeseparation": 0.06499999761581421, "pos": { "x": 0.0, "y": 0.0, "z": 4.0 } } ], "version": 1 })"; CHECK_THROWS_MATCHES( attemptValidation(config), std::exception, Catch::Matchers::Message( "At of {\"masteraddress\":\"localhost\",\"nodes\":[{\"address\":" "\"localhost\",\"port\":20401,\"windows\":[{\"border\":true,\"id\":" "0,\"monitor\":0,\"name\":\"name\",\"pos\":{\"x\":112,\"y\":77},\"size\":" "{\"x\":1280,\"y\":720},\"viewports\":[{\"pos\":{\"x\":0.0,\"y\":0.0}," "\"projection\":{\"heightoffset\":0.0,\"quality\":\"1024\",\"type\":" "\"CylindricalProjection\"},\"size\":{\"x\":1.0,\"y\":1.0},\"tracked\":" "true}]}]}],\"scene\":{\"orientation\":{\"w\":0.0,\"x\":0.0,\"y\":0.0,\"z\":" "0.0}},\"users\":[{\"eyeseparation\":0.06499999761581421,\"pos\":{\"x\":" "0.0,\"y\":0.0,\"z\":4.0}}],\"version\":1} - required property 'generator' " "not found in object\n" ) ); } TEST_CASE("SgctEdit: minimumVersion", "[sgctedit]") { const sgct::config::GeneratorVersion minVersion { "SgctWindowConfig", 1, 1 }; std::string inputCfg = absPath("${TESTDIR}/sgctedit/fails_minimum_version.json").string(); sgct::config::GeneratorVersion ver = sgct::readConfigGenerator(inputCfg); CHECK_FALSE(ver.versionCheck(minVersion)); } TEST_CASE("SgctEdit: invalidZvalue", "[sgctedit]") { const std::string config = R"({ "generator": { "major": 1, "minor": 1, "name": "SgctWindowConfig" }, "masteraddress": "localhost", "nodes": [ { "address": "localhost", "port": 20401, "windows": [ { "border": true, "id": 0, "monitor": 1, "name": "ffss", "pos": { "x": 112, "y": 77 }, "size": { "x": 1280, "y": 720, "z": s }, "viewports": [ { "pos": { "x": 0.0, "y": 0.0 }, "projection": { "heightoffset": 0.0, "quality": "1024", "type": "CylindricalProjection" }, "size": { "x": 1.0, "y": 1.0 }, "tracked": true } ] } ] } ], "scene": { "orientation": { "w": 0.0, "x": 0.0, "y": 0.0, "z": 0.0 } }, "users": [ { "eyeseparation": 0.06499999761581421, "pos": { "x": 0.0, "y": 0.0, "z": 4.0 } } ], "version": 1 })"; CHECK_THROWS_MATCHES( attemptValidation(config), std::exception, Catch::Matchers::Message( "[json.exception.parse_error.101] parse error at line 25, column 11: " "syntax error while parsing value - invalid literal; last read: '\"z\": s'" ) ); } TEST_CASE("SgctEdit: unwelcomeValue", "[sgctedit]") { const std::string config = R"({ "generator": { "major": 1, "minor": 1, "name": "SgctWindowConfig" }, "masteraddress": "localhost", "nodes": [ { "address": "localhost", "port": 20401, "windows": [ { "border": true, "id": 0, "monitor": 0, "name": "ffss", "pos": { "x": 112, "y": 77 }, "size": { "x": 1280, "y": 720 }, "viewports": [ { "pos": { "x": 0.0, "y": 0.0 }, "projection": { "heightoffset": 0.0, "quality": "1024", "type": "CylindricalProjection" }, "size": { "x": 1.0, "y": 1.0 }, "tracked": true } ] } ] } ], "scene": { "orientation": { "w": 0.0, "x": 0.0, "y": 0.0, "z": 0.0 } }, "users": [ { "extra": "???", "eyeseparation": 0.6, "pos": { "x": 0.0, "y": 0.0, "z": 4.0 } } ], "version": 1 })"; CHECK_THROWS_MATCHES( attemptValidation(config), std::exception, Catch::Matchers::Message( "At /users/0 of {\"extra\":\"???\",\"eyeseparation\":0.6,\"pos\":" "{\"x\":0.0,\"y\":0.0,\"z\":4.0}} - validation failed for additional " "property 'extra': instance invalid as per false-schema\n" ) ); }