diff --git a/include/openspace/documentation/verifier.h b/include/openspace/documentation/verifier.h index 1adcc9b140..c28cbd030e 100644 --- a/include/openspace/documentation/verifier.h +++ b/include/openspace/documentation/verifier.h @@ -235,6 +235,100 @@ struct Vector4Verifier : public TemplateVerifier>, public VectorVe std::string type() const override; }; +//---------------------------------------------------------------------------------------- +// Matrix verifiers +//---------------------------------------------------------------------------------------- + +/** +* This struct is the base class for all Verifier%s that check for \c glm matrix types. +* The template parameter for the subclasses is the containing type, not the full matrix +* type. For example to check for glm::dmat4x3, one would create a +* Matrix4x3Verifier. +*/ +struct MatrixVerifier {}; + +/** +* This Verifier checks whether the value is of type glm::mat2x2 +*/ +template +struct Matrix2x2Verifier : + public TemplateVerifier>, public MatrixVerifier +{ + std::string type() const override; +}; + +/** +* This Verifier checks whether the value is of type glm::mat2x3 +*/ +template +struct Matrix2x3Verifier : + public TemplateVerifier>, public MatrixVerifier { + std::string type() const override; +}; + +/** +* This Verifier checks whether the value is of type glm::mat2x4 +*/ +template +struct Matrix2x4Verifier : + public TemplateVerifier>, public MatrixVerifier { + std::string type() const override; +}; + +/** +* This Verifier checks whether the value is of type glm::mat3x2 +*/ +template +struct Matrix3x2Verifier : + public TemplateVerifier>, public MatrixVerifier { + std::string type() const override; +}; + +/** +* This Verifier checks whether the value is of type glm::mat3x3 +*/ +template +struct Matrix3x3Verifier : + public TemplateVerifier>, public MatrixVerifier { + std::string type() const override; +}; + +/** +* This Verifier checks whether the value is of type glm::mat3x4 +*/ +template +struct Matrix3x4Verifier : + public TemplateVerifier>, public MatrixVerifier { + std::string type() const override; +}; + +/** +* This Verifier checks whether the value is of type glm::mat4x2 +*/ +template +struct Matrix4x2Verifier : + public TemplateVerifier>, public MatrixVerifier { + std::string type() const override; +}; + +/** +* This Verifier checks whether the value is of type glm::mat4x3 +*/ +template +struct Matrix4x3Verifier : + public TemplateVerifier>, public MatrixVerifier { + std::string type() const override; +}; + +/** +* This Verifier checks whether the value is of type glm::mat4x4 +*/ +template +struct Matrix4x4Verifier : + public TemplateVerifier>, public MatrixVerifier { + std::string type() const override; +}; + //---------------------------------------------------------------------------------------- // Operator verifiers //---------------------------------------------------------------------------------------- @@ -840,6 +934,28 @@ using IntVector4Verifier = Vector4Verifier; /// A short-hand definition for a Verifier checking for glm::dvec4 using DoubleVector4Verifier = Vector4Verifier; +/// A short-hand definition for a Verifier checking for glm::dmat2x2 +using DoubleMatrix2x2Verifier = Matrix2x2Verifier; +using DoubleMatrix2Verifier = DoubleMatrix2x2Verifier; +/// A short-hand definition for a Verifier checking for glm::dmat2x3 +using DoubleMatrix2x3Verifier = Matrix2x3Verifier; +/// A short-hand definition for a Verifier checking for glm::dmat2x4 +using DoubleMatrix2x4Verifier = Matrix2x4Verifier; +/// A short-hand definition for a Verifier checking for glm::dmat3x2 +using DoubleMatrix3x2Verifier = Matrix3x2Verifier; +/// A short-hand definition for a Verifier checking for glm::dmat3x3 +using DoubleMatrix3x3Verifier = Matrix3x3Verifier; +using DoubleMatrix3Verifier = DoubleMatrix3x3Verifier; +/// A short-hand definition for a Verifier checking for glm::dmat3x4 +using DoubleMatrix3x4Verifier = Matrix3x4Verifier; +/// A short-hand definition for a Verifier checking for glm::dmat4x2 +using DoubleMatrix4x2Verifier = Matrix4x2Verifier; +/// A short-hand definition for a Verifier checking for glm::dmat4x3 +using DoubleMatrix4x3Verifier = Matrix4x3Verifier; +/// A short-hand definition for a Verifier checking for glm::dmat4x4 +using DoubleMatrix4x4Verifier = Matrix4x4Verifier; +using DoubleMatrix4Verifier = DoubleMatrix4x4Verifier; + /// A short-hand definition for a LessVerifier with a type check for \c int using IntLessVerifier = LessVerifier; /// A short-hand definition for a LessVerifier with a type check for \c double @@ -936,6 +1052,16 @@ extern template struct Vector4Verifier; extern template struct Vector4Verifier; extern template struct Vector4Verifier; +extern template struct Matrix2x2Verifier; +extern template struct Matrix2x3Verifier; +extern template struct Matrix2x4Verifier; +extern template struct Matrix3x2Verifier; +extern template struct Matrix3x3Verifier; +extern template struct Matrix3x4Verifier; +extern template struct Matrix4x2Verifier; +extern template struct Matrix4x3Verifier; +extern template struct Matrix4x4Verifier; + extern template struct LessVerifier; extern template struct LessVerifier; extern template struct LessEqualVerifier; diff --git a/include/openspace/documentation/verifier.inl b/include/openspace/documentation/verifier.inl index deaa984b3d..8df5f6e3f6 100644 --- a/include/openspace/documentation/verifier.inl +++ b/include/openspace/documentation/verifier.inl @@ -74,6 +74,69 @@ std::string Vector4Verifier::type() const { return "Vector4<"s + typeid(T).name() + ">"; } +template +std::string Matrix2x2Verifier::type() const { + using namespace std::string_literals; + + return "Matrix2x2<"s + typeid(T).name() + ">"; +} + +template +std::string Matrix2x3Verifier::type() const { + using namespace std::string_literals; + + return "Matrix2x3<"s + typeid(T).name() + ">"; +} + +template +std::string Matrix2x4Verifier::type() const { + using namespace std::string_literals; + + return "Matrix2x4<"s + typeid(T).name() + ">"; +} + +template +std::string Matrix3x2Verifier::type() const { + using namespace std::string_literals; + + return "Matrix3x2<"s + typeid(T).name() + ">"; +} + +template +std::string Matrix3x3Verifier::type() const { + using namespace std::string_literals; + + return "Matrix3x3<"s + typeid(T).name() + ">"; +} + +template +std::string Matrix3x4Verifier::type() const { + using namespace std::string_literals; + + return "Matrix3x4<"s + typeid(T).name() + ">"; +} + +template +std::string Matrix4x2Verifier::type() const { + using namespace std::string_literals; + + return "Matrix4x2<"s + typeid(T).name() + ">"; +} + +template +std::string Matrix4x3Verifier::type() const { + using namespace std::string_literals; + + return "Matrix4x3<"s + typeid(T).name() + ">"; +} + +template +std::string Matrix4x4Verifier::type() const { + using namespace std::string_literals; + + return "Matrix4x4<"s + typeid(T).name() + ">"; +} + template OperatorVerifier::OperatorVerifier(typename T::Type value) : value(std::move(value)) diff --git a/include/openspace/scene/rotation.h b/include/openspace/scene/rotation.h index 42e35bd3bd..de12533517 100644 --- a/include/openspace/scene/rotation.h +++ b/include/openspace/scene/rotation.h @@ -39,13 +39,15 @@ public: Rotation(const ghoul::Dictionary& dictionary); virtual ~Rotation(); virtual bool initialize(); - virtual const glm::dmat3& matrix() const = 0; + const glm::dmat3& matrix() const; virtual void update(const UpdateData& data); static openspace::Documentation Documentation(); protected: Rotation(); + + glm::dmat3 _matrix; }; } // namespace openspace diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index d5a0d62923..f52e3acd0f 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -136,6 +136,7 @@ void BaseModule::internalInitialize() { std::vector BaseModule::documentations() const { return { + SpiceRotation::Documentation(), StaticScale::Documentation(), StaticTranslation::Documentation(), SpiceTranslation::Documentation() diff --git a/modules/base/rotation/spicerotation.cpp b/modules/base/rotation/spicerotation.cpp index 709292554d..a1adcdc2fa 100644 --- a/modules/base/rotation/spicerotation.cpp +++ b/modules/base/rotation/spicerotation.cpp @@ -24,6 +24,8 @@ #include +#include + #include #include @@ -38,56 +40,90 @@ namespace { namespace openspace { -SpiceRotation::SpiceRotation(const ghoul::Dictionary& dictionary) - : _sourceFrame("") - , _destinationFrame("") - , _rotationMatrix(1.0) - , _kernelsLoadedSuccessfully(true) -{ - const bool hasSourceFrame = dictionary.getValue(KeySourceFrame, _sourceFrame); - if (!hasSourceFrame) - LERROR("SpiceRotation does not contain the key '" << KeySourceFrame << "'"); - - const bool hasDestinationFrame = dictionary.getValue(KeyDestinationFrame, _destinationFrame); - if (!hasDestinationFrame) - LERROR("SpiceRotation does not contain the key '" << KeyDestinationFrame << "'"); - - ghoul::Dictionary kernels; - dictionary.getValue(KeyKernels, kernels); - for (size_t i = 1; i <= kernels.size(); ++i) { - std::string kernel; - bool success = kernels.getValue(std::to_string(i), kernel); - if (!success) - LERROR("'" << KeyKernels << "' has to be an array-style table"); - - try { - SpiceManager::ref().loadKernel(kernel); - _kernelsLoadedSuccessfully = true; +Documentation SpiceRotation::Documentation() { + using namespace openspace::documentation; + return { + "Spice Rotation", + "base_transform_rotation_spice", + { + { + "Type", + new StringEqualVerifier("SpiceRotation"), + "", + Optional::No + }, + { + KeySourceFrame, + new StringAnnotationVerifier("A valid SPICE NAIF name or integer"), + "The source frame that is used as the basis for the coordinate " + "transformation. This has to be a valid SPICE name.", + Optional::No + }, + { + KeyDestinationFrame, + new StringAnnotationVerifier("A valid SPICE NAIF name or integer"), + "The destination frame that is used for the coordinate transformation. " + "This has to be a valid SPICE name.", + Optional::No + }, + { + KeyKernels, + new OrVerifier( + new TableVerifier({ + { "*", new StringVerifier } + }), + new StringVerifier + ), + "A single kernel or list of kernels that this SpiceTranslation depends " + "on. All provided kernels will be loaded before any other operation is " + "performed.", + Optional::Yes + } } - catch (const SpiceManager::SpiceException& e) { - LERROR("Could not load SPICE kernel: " << e.what()); - _kernelsLoadedSuccessfully = false; + }; +} + +SpiceRotation::SpiceRotation(const ghoul::Dictionary& dictionary) + : _sourceFrame("source", "Source", "") + , _destinationFrame("destination", "Destination", "") +{ + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "SpiceRotation" + ); + + _sourceFrame = dictionary.value(KeySourceFrame); + _destinationFrame = dictionary.value(KeyDestinationFrame); + + if (dictionary.hasKeyAndValue(KeyKernels)) { + SpiceManager::ref().loadKernel(dictionary.value(KeyKernels)); + } + else if (dictionary.hasKeyAndValue(KeyKernels)) { + ghoul::Dictionary kernels = dictionary.value(KeyKernels); + for (size_t i = 1; i <= kernels.size(); ++i) { + if (!kernels.hasKeyAndValue(std::to_string(i))) { + throw ghoul::RuntimeError("Kernels has to be an array-style table"); + } + + std::string kernel = kernels.value(std::to_string(i)); + SpiceManager::ref().loadKernel(kernel); } } } -const glm::dmat3& SpiceRotation::matrix() const { - return _rotationMatrix; -} - void SpiceRotation::update(const UpdateData& data) { - if (!_kernelsLoadedSuccessfully) - return; try { - _rotationMatrix = SpiceManager::ref().positionTransformMatrix( + _matrix = SpiceManager::ref().positionTransformMatrix( _sourceFrame, _destinationFrame, - data.time); + data.time + ); } catch (const ghoul::RuntimeError&) { // In case of missing coverage - _rotationMatrix = glm::dmat3(1); + _matrix = glm::dmat3(1); } } -} // namespace openspace \ No newline at end of file +} // namespace openspace diff --git a/modules/base/rotation/spicerotation.h b/modules/base/rotation/spicerotation.h index 034ff7fece..4c3cecf729 100644 --- a/modules/base/rotation/spicerotation.h +++ b/modules/base/rotation/spicerotation.h @@ -26,20 +26,22 @@ #define __SPICEROTATION_H__ #include +#include +#include namespace openspace { class SpiceRotation : public Rotation { public: SpiceRotation(const ghoul::Dictionary& dictionary); - virtual const glm::dmat3& matrix() const; + const glm::dmat3& matrix() const; void update(const UpdateData& data) override; + static openspace::Documentation Documentation(); + private: - std::string _sourceFrame; - std::string _destinationFrame; - glm::dmat3 _rotationMatrix; - bool _kernelsLoadedSuccessfully; + properties::StringProperty _sourceFrame; + properties::StringProperty _destinationFrame; }; } // namespace openspace diff --git a/modules/base/rotation/staticrotation.cpp b/modules/base/rotation/staticrotation.cpp index a009fa571e..f44e768c6e 100644 --- a/modules/base/rotation/staticrotation.cpp +++ b/modules/base/rotation/staticrotation.cpp @@ -24,29 +24,66 @@ #include +#include + namespace { - const std::string KeyEulerAngles = "EulerAngles"; + const std::string KeyRotation = "Rotation"; } namespace openspace { +Documentation StaticRotation::Documentation() { + using namespace openspace::documentation; + return { + "Static Rotation", + "base_transform_rotation_static", + { + { + "Type", + new StringEqualVerifier("StaticRotation"), + "", + Optional::No + }, + { + KeyRotation, + new OrVerifier( + new DoubleVector3Verifier(), + new DoubleMatrix3Verifier() + ), + "Stores the static rotation as either a vector containing Euler angles " + "or by specifiying the 3x3 rotation matrix directly", + Optional::No + } + }, + Exhaustive::Yes + }; +} + +StaticRotation::StaticRotation() + : _rotationMatrix("rotation", "Rotation", glm::dmat3(1.0)) +{} + StaticRotation::StaticRotation(const ghoul::Dictionary& dictionary) - : _rotationMatrix(1.0) + : StaticRotation() { - const bool hasEulerAngles = dictionary.hasKeyAndValue(KeyEulerAngles); - if (hasEulerAngles) { - glm::dvec3 tmp; - dictionary.getValue(KeyEulerAngles, tmp); - _rotationMatrix = glm::mat3_cast(glm::dquat(tmp)); + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "StaticRotation" + ); + + + if (dictionary.hasKeyAndValue(KeyRotation)) { + _rotationMatrix = glm::mat3_cast( + glm::dquat(dictionary.value(KeyRotation)) + ); } + else { + // Must be glm::dmat3 due to specification restriction + _rotationMatrix = dictionary.value(KeyRotation); + } + + _rotationMatrix.onChange([this]() { _matrix = _rotationMatrix; }); } -StaticRotation::~StaticRotation() {} - -const glm::dmat3& StaticRotation::matrix() const { - return _rotationMatrix; -} - -void StaticRotation::update(const UpdateData&) {} - -} // namespace openspace \ No newline at end of file +} // namespace openspace diff --git a/modules/base/rotation/staticrotation.h b/modules/base/rotation/staticrotation.h index 4474081057..8df5c8637e 100644 --- a/modules/base/rotation/staticrotation.h +++ b/modules/base/rotation/staticrotation.h @@ -27,17 +27,20 @@ #include +#include +#include + namespace openspace { -class StaticRotation: public Rotation { +class StaticRotation : public Rotation { public: - StaticRotation(const ghoul::Dictionary& dictionary - = ghoul::Dictionary()); - virtual ~StaticRotation(); - virtual const glm::dmat3& matrix() const; - virtual void update(const UpdateData& data) override; + StaticRotation(); + StaticRotation(const ghoul::Dictionary& dictionary); + + static openspace::Documentation Documentation(); + private: - glm::dmat3 _rotationMatrix; + properties::DMat3Property _rotationMatrix; }; } // namespace openspace diff --git a/src/documentation/core_registration.cpp b/src/documentation/core_registration.cpp index 8777700213..4f87a5ee20 100644 --- a/src/documentation/core_registration.cpp +++ b/src/documentation/core_registration.cpp @@ -35,11 +35,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include @@ -54,7 +54,6 @@ namespace openspace { void registerCoreClasses(documentation::DocumentationEngine& engine) { engine.addDocumentation(ConfigurationManager::Documentation()); - engine.addDocumentation(Translation::Documentation()); engine.addDocumentation(Mission::Documentation()); engine.addDocumentation(Renderable::Documentation()); engine.addDocumentation(Rotation::Documentation()); @@ -63,6 +62,7 @@ void registerCoreClasses(documentation::DocumentationEngine& engine) { engine.addDocumentation(SceneGraphNode::Documentation()); engine.addDocumentation(ScreenSpaceRenderable::Documentation()); engine.addDocumentation(TimeRange::Documentation()); + engine.addDocumentation(Translation::Documentation()); } void registerCoreClasses(scripting::ScriptEngine& engine) { diff --git a/src/documentation/verifier.cpp b/src/documentation/verifier.cpp index 4c68386f7c..540f9b9439 100644 --- a/src/documentation/verifier.cpp +++ b/src/documentation/verifier.cpp @@ -41,6 +41,16 @@ template struct Vector4Verifier; template struct Vector4Verifier; template struct Vector4Verifier; +template struct Matrix2x2Verifier; +template struct Matrix2x3Verifier; +template struct Matrix2x4Verifier; +template struct Matrix3x2Verifier; +template struct Matrix3x3Verifier; +template struct Matrix3x4Verifier; +template struct Matrix4x2Verifier; +template struct Matrix4x3Verifier; +template struct Matrix4x4Verifier; + template struct LessVerifier; template struct LessVerifier; template struct LessEqualVerifier; diff --git a/src/scene/rotation.cpp b/src/scene/rotation.cpp index a4d77d54ff..e098274235 100644 --- a/src/scene/rotation.cpp +++ b/src/scene/rotation.cpp @@ -79,6 +79,10 @@ bool Rotation::initialize() { return true; } +const glm::dmat3& Rotation::matrix() const { + return _matrix; +} + void Rotation::update(const UpdateData& data) {} } // namespace openspace \ No newline at end of file diff --git a/tests/test_documentation.inl b/tests/test_documentation.inl index da672ca414..07e256f068 100644 --- a/tests/test_documentation.inl +++ b/tests/test_documentation.inl @@ -2308,6 +2308,303 @@ TEST_F(DocumentationTest, DoubleVector4Verifier) { EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); } +TEST_F(DocumentationTest, DoubleMatrix2x2Verifier) { + using namespace openspace::documentation; + + Documentation doc { + { { "a", new DoubleMatrix2x2Verifier } } + }; + + ghoul::Dictionary positive { + { "a", glm::dmat2x2(1.0) } + }; + TestResult positiveRes = testSpecification(doc, positive); + EXPECT_TRUE(positiveRes.success); + EXPECT_EQ(0, positiveRes.offenses.size()); + + ghoul::Dictionary negative { + { "a", ghoul::Dictionary { { "1", true },{ "2", 1.0 },{ "3", "s" } } } + }; + TestResult negativeRes = testSpecification(doc, negative); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); + + ghoul::Dictionary negative2 { + { "a", true } + }; + negativeRes = testSpecification(doc, negative2); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); +} + +TEST_F(DocumentationTest, DoubleMatrix2x3Verifier) { + using namespace openspace::documentation; + + Documentation doc { + { { "a", new DoubleMatrix2x3Verifier } } + }; + + ghoul::Dictionary positive { + { "a", glm::dmat2x3(1.0) } + }; + TestResult positiveRes = testSpecification(doc, positive); + EXPECT_TRUE(positiveRes.success); + EXPECT_EQ(0, positiveRes.offenses.size()); + + ghoul::Dictionary negative { + { "a", ghoul::Dictionary{ { "1", true },{ "2", 1.0 },{ "3", "s" } } } + }; + TestResult negativeRes = testSpecification(doc, negative); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); + + ghoul::Dictionary negative2 { + { "a", true } + }; + negativeRes = testSpecification(doc, negative2); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); +} + +TEST_F(DocumentationTest, DoubleMatrix2x4Verifier) { + using namespace openspace::documentation; + + Documentation doc { + { { "a", new DoubleMatrix2x4Verifier } } + }; + + ghoul::Dictionary positive { + { "a", glm::dmat2x4(1.0) } + }; + TestResult positiveRes = testSpecification(doc, positive); + EXPECT_TRUE(positiveRes.success); + EXPECT_EQ(0, positiveRes.offenses.size()); + + ghoul::Dictionary negative { + { "a", ghoul::Dictionary{ { "1", true },{ "2", 1.0 },{ "3", "s" } } } + }; + TestResult negativeRes = testSpecification(doc, negative); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); + + ghoul::Dictionary negative2 { + { "a", true } + }; + negativeRes = testSpecification(doc, negative2); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); +} + +TEST_F(DocumentationTest, DoubleMatrix3x2Verifier) { + using namespace openspace::documentation; + + Documentation doc { + { { "a", new DoubleMatrix3x2Verifier } } + }; + + ghoul::Dictionary positive { + { "a", glm::dmat3x2(1.0) } + }; + TestResult positiveRes = testSpecification(doc, positive); + EXPECT_TRUE(positiveRes.success); + EXPECT_EQ(0, positiveRes.offenses.size()); + + ghoul::Dictionary negative { + { "a", ghoul::Dictionary{ { "1", true },{ "2", 1.0 },{ "3", "s" } } } + }; + TestResult negativeRes = testSpecification(doc, negative); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); + + ghoul::Dictionary negative2 { + { "a", true } + }; + negativeRes = testSpecification(doc, negative2); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); +} + +TEST_F(DocumentationTest, DoubleMatrix3x3Verifier) { + using namespace openspace::documentation; + + Documentation doc { + { { "a", new DoubleMatrix3x3Verifier } } + }; + + ghoul::Dictionary positive { + { "a", glm::dmat3x3(1.0) } + }; + TestResult positiveRes = testSpecification(doc, positive); + EXPECT_TRUE(positiveRes.success); + EXPECT_EQ(0, positiveRes.offenses.size()); + + ghoul::Dictionary negative { + { "a", ghoul::Dictionary{ { "1", true },{ "2", 1.0 },{ "3", "s" } } } + }; + TestResult negativeRes = testSpecification(doc, negative); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); + + ghoul::Dictionary negative2 { + { "a", true } + }; + negativeRes = testSpecification(doc, negative2); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); +} + +TEST_F(DocumentationTest, DoubleMatrix3x4Verifier) { + using namespace openspace::documentation; + + Documentation doc { + { { "a", new DoubleMatrix3x4Verifier } } + }; + + ghoul::Dictionary positive { + { "a", glm::dmat3x4(1.0) } + }; + TestResult positiveRes = testSpecification(doc, positive); + EXPECT_TRUE(positiveRes.success); + EXPECT_EQ(0, positiveRes.offenses.size()); + + ghoul::Dictionary negative { + { "a", ghoul::Dictionary{ { "1", true },{ "2", 1.0 },{ "3", "s" } } } + }; + TestResult negativeRes = testSpecification(doc, negative); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); + + ghoul::Dictionary negative2 { + { "a", true } + }; + negativeRes = testSpecification(doc, negative2); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); +} + +TEST_F(DocumentationTest, DoubleMatrix4x2Verifier) { + using namespace openspace::documentation; + + Documentation doc { + { { "a", new DoubleMatrix4x2Verifier } } + }; + + ghoul::Dictionary positive { + { "a", glm::dmat4x2(1.0) } + }; + TestResult positiveRes = testSpecification(doc, positive); + EXPECT_TRUE(positiveRes.success); + EXPECT_EQ(0, positiveRes.offenses.size()); + + ghoul::Dictionary negative { + { "a", ghoul::Dictionary{ { "1", true },{ "2", 1.0 },{ "3", "s" } } } + }; + TestResult negativeRes = testSpecification(doc, negative); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); + + ghoul::Dictionary negative2 { + { "a", true } + }; + negativeRes = testSpecification(doc, negative2); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); +} + +TEST_F(DocumentationTest, DoubleMatrix4x3Verifier) { + using namespace openspace::documentation; + + Documentation doc { + { { "a", new DoubleMatrix4x3Verifier } } + }; + + ghoul::Dictionary positive { + { "a", glm::dmat4x3(1.0) } + }; + TestResult positiveRes = testSpecification(doc, positive); + EXPECT_TRUE(positiveRes.success); + EXPECT_EQ(0, positiveRes.offenses.size()); + + ghoul::Dictionary negative { + { "a", ghoul::Dictionary{ { "1", true },{ "2", 1.0 },{ "3", "s" } } } + }; + TestResult negativeRes = testSpecification(doc, negative); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); + + ghoul::Dictionary negative2 { + { "a", true } + }; + negativeRes = testSpecification(doc, negative2); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); +} + +TEST_F(DocumentationTest, DoubleMatrix4x4Verifier) { + using namespace openspace::documentation; + + Documentation doc { + { { "a", new DoubleMatrix4x4Verifier } } + }; + + ghoul::Dictionary positive { + { "a", glm::dmat4x4(1.0) } + }; + TestResult positiveRes = testSpecification(doc, positive); + EXPECT_TRUE(positiveRes.success); + EXPECT_EQ(0, positiveRes.offenses.size()); + + ghoul::Dictionary negative { + { "a", ghoul::Dictionary{ { "1", true },{ "2", 1.0 },{ "3", "s" } } } + }; + TestResult negativeRes = testSpecification(doc, negative); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); + + ghoul::Dictionary negative2 { + { "a", true } + }; + negativeRes = testSpecification(doc, negative2); + EXPECT_FALSE(negativeRes.success); + ASSERT_EQ(1, negativeRes.offenses.size()); + EXPECT_EQ("a", negativeRes.offenses[0].offender); + EXPECT_EQ(TestResult::Offense::Reason::WrongType, negativeRes.offenses[0].reason); +} + TEST_F(DocumentationTest, DeprecatedVerifier) { using namespace openspace::documentation; using namespace std::string_literals;