Files
OpenSpace/tests/test_configurationmanager.inl
2017-12-29 20:11:22 +01:00

1117 lines
42 KiB
C++

/*****************************************************************************************
* *
* GHOUL *
* General Helpful Open Utility Library *
* *
* Copyright (c) 2012-2018 *
* *
* 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 <ghoul/glm.h>
#include <fstream>
#include <random>
#include <ghoul/misc/configurationmanager.h>
#include <ghoul/filesystem/filesystem>
namespace {
// A non-existing configuration file
const std::string _configuration0 = "${TEST_DIR}/configurationmanager/test0.cfg";
// The configuration1 test configuration has one key "t" = 1
const std::string _configuration1 = "${TEST_DIR}/configurationmanager/test1.cfg";
// The configuration1 test configuration has two keys "t" and "s"
const std::string _configuration2 = "${TEST_DIR}/configurationmanager/test2.cfg";
// More complicated configuration file with nested tables
const std::string _configuration3 = "${TEST_DIR}/configurationmanager/test3.cfg";
// Deeply nested configuration file with 12 level
const std::string _configuration4 = "${TEST_DIR}/configurationmanager/test4.cfg";
// Testfile with glm::vecX, glm::matX
const std::string _configuration5 = "${TEST_DIR}/configurationmanager/test5.cfg";
}
/*
Test checklist:
--- loadConfiguration: existing file
--- loadConfiguration: non-existing file
--- getValue: key does not exist
--- getValue: subtable does not exist
--- getValue: overriding previous configuration
--- getValue: function does not change passed value on error
--- getValue: nested keys
--- getValue: deep nesting of keys
--- getValue: correct values returned for each type
--- getValue: are all basic types implemented
--- getValue: glm::vec2, glm::vec3, glm::vec4 implemented
--- getValue: glm::matXxY implemented
--- getValue: valid conversions
--- setValue: all types implemented
--- setValue: create subtables on the way
--- setValue: value gets set correctly for each type
--- setValue: value overwrites setting in configuration file
--- setValue: deep nesting of keys
--- setValue: nested keys
--- setValue: glm::vec2, glm::vec3, glm::vec4, glm::mat3, glm::mat4 implemented
--- hasKeys: deep nesting of keys
--- hasKeys: subtables on the way do not exist
--- hasKeys: correct values for all types
--- hasKeys: nestedKeys
--- timing
*/
class ConfigurationManagerTest : public testing::Test {
protected:
ConfigurationManagerTest() {
_m = new ghoul::ConfigurationManager;
}
~ConfigurationManagerTest() {
if (_m) {
delete _m;
_m = nullptr;
}
}
void reset() {
_m->clear();
}
ghoul::ConfigurationManager* _m;
};
#ifdef GHL_TIMING_TESTS
TEST_F(ConfigurationManagerTest, TimingTest) {
std::ofstream logFile("ConfigurationManagerTest.timing");
START_TIMER(loadConfiguration1, logFile, 25);
_m->loadConfiguration(_configuration1);
FINISH_TIMER(loadConfiguration1, logFile);
START_TIMER(loadConfiguration2, logFile, 25);
_m->loadConfiguration(_configuration2);
FINISH_TIMER(loadConfiguration2, logFile);
START_TIMER(loadConfiguration3, logFile, 25);
_m->loadConfiguration(_configuration3);
FINISH_TIMER(loadConfiguration3, logFile);
START_TIMER(loadConfiguration4, logFile, 25);
_m->loadConfiguration(_configuration4);
FINISH_TIMER(loadConfiguration4, logFile);
START_TIMER(loadConfiguration5, logFile, 25);
_m->loadConfiguration(_configuration5);
FINISH_TIMER(loadConfiguration5, logFile);
START_TIMER(loadConfiguration12, logFile, 25);
_m->loadConfiguration(_configuration1);
_m->loadConfiguration(_configuration2);
FINISH_TIMER(loadConfiguration12, logFile);
START_TIMER(loadConfiguration123, logFile, 25);
_m->loadConfiguration(_configuration1);
_m->loadConfiguration(_configuration2);
_m->loadConfiguration(_configuration3);
FINISH_TIMER(loadConfiguration123, logFile);
START_TIMER(loadConfiguration1234, logFile, 25);
_m->loadConfiguration(_configuration1);
_m->loadConfiguration(_configuration2);
_m->loadConfiguration(_configuration3);
_m->loadConfiguration(_configuration4);
FINISH_TIMER(loadConfiguration1234, logFile);
START_TIMER(loadConfiguration12345, logFile, 25);
_m->loadConfiguration(_configuration1);
_m->loadConfiguration(_configuration2);
_m->loadConfiguration(_configuration3);
_m->loadConfiguration(_configuration4);
_m->loadConfiguration(_configuration5);
FINISH_TIMER(loadConfiguration12345, logFile);
START_TIMER(setValueLevel0Int, logFile, 25);
_m->setValue("t", 1);
FINISH_TIMER(setValueLevel0Int, logFile);
START_TIMER(setValueLevel1Int, logFile, 25);
_m->setValue("t.t", 1);
FINISH_TIMER(setValueLevel1Int, logFile);
START_TIMER(setValueLevel10Int, logFile, 25);
_m->setValue("t.t.t.t.t.t.t.t.t.t", 1);
FINISH_TIMER(setValueLevel10Int, logFile);
START_TIMER(setValueLevel0dvec4, logFile, 25);
_m->setValue("t", glm::dvec4(1.0));
FINISH_TIMER(setValueLevel0dvec4, logFile);
START_TIMER(setValueLevel0dmat4, logFile, 25);
_m->setValue("t", glm::dmat4(1.0));
FINISH_TIMER(setValueLevel0dmat4, logFile);
{
int i;
START_TIMER_PREPARE(getValueLevel0Int, logFile, 25, {_m->setValue("t", 1);});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel0Int, logFile);
START_TIMER(getValueLevel0IntEmpty, logFile, 25);
_m->getValue("t", i);
FINISH_TIMER(getValueLevel0IntEmpty, logFile);
START_TIMER_PREPARE(getValueLevel1Int, logFile, 25, {_m->setValue("t.t", 1);});
_m->getValue("t.t", i);
FINISH_TIMER(getValueLevel1Int, logFile);
START_TIMER_PREPARE(getValueLevel10Int, logFile, 25,
{_m->setValue("t.t.t.t.t.t.t.t.t.t", 1);});
_m->getValue("t.t.t.t.t.t.t.t.t.t", i);
FINISH_TIMER(getValueLevel10Int, logFile);
START_TIMER(getValueLevel10IntEmpty, logFile, 25);
_m->getValue("t.t.t.t.t.t.t.t.t.t", i);
FINISH_TIMER(getValueLevel10IntEmpty, logFile);
}
{
START_TIMER(setValueLevel1vec2, logFile, 25);
_m->setValue("t", glm::vec2(1.0));
FINISH_TIMER(setValueLevel1vec2, logFile);
}
{
START_TIMER(setValueLevel1vec3, logFile, 25);
_m->setValue("t", glm::vec3(1.0));
FINISH_TIMER(setValueLevel1vec3, logFile);
}
{
START_TIMER(setValueLevel1vec4, logFile, 25);
_m->setValue("t", glm::vec4(1.0));
FINISH_TIMER(setValueLevel1vec4, logFile);
}
{
START_TIMER(setValueLevel1dvec2, logFile, 25);
_m->setValue("t", glm::dvec2(1.0));
FINISH_TIMER(setValueLevel1dvec2, logFile);
}
{
START_TIMER(setValueLevel1dvec3, logFile, 25);
_m->setValue("t", glm::dvec3(1.0));
FINISH_TIMER(setValueLevel1dvec3, logFile);
}
{
START_TIMER(setValueLevel1dvec4, logFile, 25);
_m->setValue("t", glm::dvec4(1.0));
FINISH_TIMER(setValueLevel1dvec4, logFile);
}
{
START_TIMER(setValueLevel1ivec2, logFile, 25);
_m->setValue("t", glm::ivec2(1.0));
FINISH_TIMER(setValueLevel1ivec2, logFile);
}
{
START_TIMER(setValueLevel1ivec3, logFile, 25);
_m->setValue("t", glm::ivec3(1.0));
FINISH_TIMER(setValueLevel1ivec3, logFile);
}
{
START_TIMER(setValueLevel1ivec4, logFile, 25);
_m->setValue("t", glm::ivec4(1.0));
FINISH_TIMER(setValueLevel1ivec4, logFile);
}
{
START_TIMER(setValueLevel1bvec2, logFile, 25);
_m->setValue("t", glm::bvec2(true));
FINISH_TIMER(setValueLevel1bvec2, logFile);
}
{
START_TIMER(setValueLevel1bvec3, logFile, 25);
_m->setValue("t", glm::bvec3(true));
FINISH_TIMER(setValueLevel1bvec3, logFile);
}
{
START_TIMER(setValueLevel1bvec4, logFile, 25);
_m->setValue("t", glm::bvec4(true));
FINISH_TIMER(setValueLevel1bvec4, logFile);
}
{
START_TIMER(setValueLevel1uvec2, logFile, 25);
_m->setValue("t", glm::uvec2(1.0));
FINISH_TIMER(setValueLevel1uvec2, logFile);
}
{
START_TIMER(setValueLevel1uvec3, logFile, 25);
_m->setValue("t", glm::uvec3(1.0));
FINISH_TIMER(setValueLevel1uvec3, logFile);
}
{
START_TIMER(setValueLevel1uvec4, logFile, 25);
_m->setValue("t", glm::uvec4(1.0));
FINISH_TIMER(setValueLevel1uvec4, logFile);
}
{
START_TIMER(setValueLevel1dmat2x4, logFile, 25);
_m->setValue("t", glm::dmat2x4(1.0));
FINISH_TIMER(setValueLevel1dmat2x4, logFile);
}
{
START_TIMER(setValueLevel1dmat2x3, logFile, 25);
_m->setValue("t", glm::dmat2x3(1.0));
FINISH_TIMER(setValueLevel1dmat2x3, logFile);
}
{
START_TIMER(setValueLevel1dmat2, logFile, 25);
_m->setValue("t", glm::dmat2(1.0));
FINISH_TIMER(setValueLevel1dmat2, logFile);
}
{
START_TIMER(setValueLevel1dmat3x2, logFile, 25);
_m->setValue("t", glm::dmat3x2(1.0));
FINISH_TIMER(setValueLevel1dmat3x2, logFile);
}
{
START_TIMER(setValueLevel1dmat3x4, logFile, 25);
_m->setValue("t", glm::dmat3x4(1.0));
FINISH_TIMER(setValueLevel1dmat3x4, logFile);
}
{
START_TIMER(setValueLevel1dmat3, logFile, 25);
_m->setValue("t", glm::dmat3(1.0));
FINISH_TIMER(setValueLevel1dmat3, logFile);
}
{
START_TIMER(setValueLevel1dmat4x2, logFile, 25);
_m->setValue("t", glm::dmat4x3(1.0));
FINISH_TIMER(setValueLevel1dmat4x2, logFile);
}
{
START_TIMER(setValueLevel1dmat4x3, logFile, 25);
_m->setValue("t", glm::dmat4x3(1.0));
FINISH_TIMER(setValueLevel1dmat4x3, logFile);
}
{
START_TIMER(setValueLevel1dmat4, logFile, 25);
_m->setValue("t", glm::dmat4(1.0));
FINISH_TIMER(setValueLevel1dmat4, logFile);
}
{
glm::vec2 i;
START_TIMER_PREPARE(getValueLevel1vec2, logFile, 25,
{_m->setValue("t", glm::vec2(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1vec2, logFile);
}
{
glm::vec3 i;
START_TIMER_PREPARE(getValueLevel1vec3, logFile, 25,
{_m->setValue("t", glm::vec3(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1vec3, logFile);
}
{
glm::vec4 i;
START_TIMER_PREPARE(getValueLevel1vec4, logFile, 25,
{_m->setValue("t", glm::vec4(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1vec4, logFile);
}
{
glm::dvec2 i;
START_TIMER_PREPARE(getValueLevel1dvec2, logFile, 25,
{_m->setValue("t", glm::dvec2(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1dvec2, logFile);
}
{
glm::dvec3 i;
START_TIMER_PREPARE(getValueLevel1dvec3, logFile, 25,
{_m->setValue("t", glm::dvec3(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1dvec3, logFile);
}
{
glm::dvec4 i;
START_TIMER_PREPARE(getValueLevel1dvec4, logFile, 25,
{_m->setValue("t", glm::dvec4(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1dvec4, logFile);
}
{
glm::ivec2 i;
START_TIMER_PREPARE(getValueLevel1ivec2, logFile, 25,
{_m->setValue("t", glm::ivec2(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1ivec2, logFile);
}
{
glm::ivec3 i;
START_TIMER_PREPARE(getValueLevel1ivec3, logFile, 25,
{_m->setValue("t", glm::ivec3(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1ivec3, logFile);
}
{
glm::ivec4 i;
START_TIMER_PREPARE(getValueLevel1ivec4, logFile, 25,
{_m->setValue("t", glm::ivec4(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1ivec4, logFile);
}
{
glm::bvec2 i;
START_TIMER_PREPARE(getValueLevel1bvec2, logFile, 25,
{_m->setValue("t", glm::bvec2(true));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1bvec2, logFile);
}
{
glm::bvec3 i;
START_TIMER_PREPARE(getValueLevel1bvec3, logFile, 25,
{_m->setValue("t", glm::bvec3(true));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1bvec3, logFile);
}
{
glm::bvec4 i;
START_TIMER_PREPARE(getValueLevel1bvec4, logFile, 25,
{_m->setValue("t", glm::bvec4(true));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1bvec4, logFile);
}
{
glm::uvec2 i;
START_TIMER_PREPARE(getValueLevel1uvec2, logFile, 25,
{_m->setValue("t", glm::uvec2(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1uvec2, logFile);
}
{
glm::uvec3 i;
START_TIMER_PREPARE(getValueLevel1uvec3, logFile, 25,
{_m->setValue("t", glm::uvec3(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1uvec3, logFile);
}
{
glm::uvec4 i;
START_TIMER_PREPARE(getValueLevel1uvec4, logFile, 25,
{_m->setValue("t", glm::uvec4(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1uvec4, logFile);
}
{
glm::dmat2x4 i;
START_TIMER_PREPARE(getValueLevel1dmat2x4, logFile, 25,
{_m->setValue("t", glm::dmat2x4(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1dmat2x4, logFile);
}
{
glm::dmat2x3 i;
START_TIMER_PREPARE(getValueLevel1dmat2x3, logFile, 25,
{_m->setValue("t", glm::dmat2x3(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1dmat2x3, logFile);
}
{
glm::dmat2 i;
START_TIMER_PREPARE(getValueLevel1dmat2, logFile, 25,
{_m->setValue("t", glm::dmat2(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1dmat2, logFile);
}
{
glm::dmat3x2 i;
START_TIMER_PREPARE(getValueLevel1dmat3x2, logFile, 25,
{_m->setValue("t", glm::dmat3x2(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1dmat3x2, logFile);
}
{
glm::dmat3x4 i;
START_TIMER_PREPARE(getValueLevel1dmat3x4, logFile, 25,
{_m->setValue("t", glm::dmat3x4(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1dmat3x4, logFile);
}
{
glm::dmat3 i;
START_TIMER_PREPARE(getValueLevel1dmat3, logFile, 25,
{_m->setValue("t", glm::dmat3(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1dmat3, logFile);
}
{
glm::dmat4x2 i;
START_TIMER_PREPARE(getValueLevel1dmat4x2, logFile, 25,
{_m->setValue("t", glm::dmat4x2(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1dmat4x2, logFile);
}
{
glm::dmat4x3 i;
START_TIMER_PREPARE(getValueLevel1dmat4x3, logFile, 25,
{_m->setValue("t", glm::dmat4x3(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1dmat4x3, logFile);
}
{
glm::dmat4 i;
START_TIMER_PREPARE(getValueLevel1dmat4, logFile, 25,
{_m->setValue("t", glm::dmat4(1.0));});
_m->getValue("t", i);
FINISH_TIMER(getValueLevel1dmat4, logFile);
}
START_TIMER(hasKeyLevel0Empty, logFile, 25);
_m->hasKey("t");
FINISH_TIMER(hasKeyLevel0Empty, logFile);
START_TIMER(hasKeyLevel10Empty, logFile, 25);
_m->hasKey("t.t.t.t.t.t.t.t.t.t");
FINISH_TIMER(hasKeyLevel10Empty, logFile);
START_TIMER_PREPARE(hasKeyLevel0, logFile, 25, {_m->setValue("t", 1);});
_m->hasKey("t");
FINISH_TIMER(hasKeyLevel0, logFile);
START_TIMER_PREPARE(hasKeyLevel10, logFile, 25,
{_m->setValue("t.t.t.t.t.t.t.t.t.t", 1);});
_m->hasKey("t.t.t.t.t.t.t.t.t.t");
FINISH_TIMER(hasKeyLevel10, logFile);
}
#endif // GHL_TIMING_TESTS
TEST_F(ConfigurationManagerTest, ReinitTest) {
_m->setValue("t", int(2));
_m->clear();
const bool success = _m->hasKey("t");
EXPECT_EQ(false, success);
}
TEST_F(ConfigurationManagerTest, LoadConfigurationTest) {
const bool success0 = _m->loadConfiguration(_configuration0);
ASSERT_EQ(false, success0) << "Loading a non-existing file should fail gracefully";
const bool success1 = _m->loadConfiguration(_configuration1);
ASSERT_EQ(true, success1) << "Loading of configuration file 'test1.cfg'";
const bool success2 = _m->loadConfiguration(_configuration2);
ASSERT_EQ(true, success2) << "Loading of configuration file 'test2.cfg'";
const bool success3 = _m->loadConfiguration(_configuration3);
ASSERT_EQ(true, success3) << "Loading of configuration file 'test3.cfg'";
const bool success4 = _m->loadConfiguration(_configuration4);
ASSERT_EQ(true, success4) << "Loading of configuration file 'test4.cfg'";
}
TEST_F(ConfigurationManagerTest, KeysFunction) {
// The empty configuration should not have any keys
size_t nKeys = _m->keys().size();
EXPECT_EQ(0, nKeys) << "The empty configuration should not have any keys";
_m->loadConfiguration(_configuration1);
nKeys = _m->keys().size();
EXPECT_EQ(1, nKeys) << "test1";
_m->loadConfiguration(_configuration3);
nKeys = _m->keys().size();
EXPECT_EQ(3, nKeys) << "base: test1 + test3";
nKeys = _m->keys("s").size();
EXPECT_EQ(3, nKeys) << "s: test1 + test3";
nKeys = _m->keys("s.3").size();
EXPECT_EQ(2, nKeys) << "s.3: test1 + test3";
_m->loadConfiguration(_configuration4);
const char* keys[] = {
"a", "a.a", "a.a.a", "a.a.a.a", "a.a.a.a.a", "a.a.a.a.a.a", "a.a.a.a.a.a.a",
"a.a.a.a.a.a.a.a", "a.a.a.a.a.a.a.a.a", "a.a.a.a.a.a.a.a.a.a",
"a.a.a.a.a.a.a.a.a.a.a", "a.a.a.a.a.a.a.a.a.a.a.a"
};
for (int i = 0; i < 12; ++i) {
nKeys = _m->keys(keys[i]).size();
EXPECT_EQ(2, nKeys) << keys[i] <<": test1 + test3";
}
for (int i = 0; i < 12; ++i) {
const bool hasKey = _m->hasKey(keys[i]);
EXPECT_EQ(true, hasKey) << keys[i] <<": test1 + test3";
}
const char* keysB[] = {
"b", "b.b", "b.b.b", "b.b.b.b", "b.b.b.b.b", "b.b.b.b.b.b", "b.b.b.b.b.b.b",
"b.b.b.b.b.b.b.b", "b.b.b.b.b.b.b.b.b", "b.b.b.b.b.b.b.b.b.b",
"b.b.b.b.b.b.b.b.b.b.b", "b.b.b.b.b.b.b.b.b.b.b.b"
};
_m->setValue(keysB[11], int(0), true);
for (int i = 0; i < 12; ++i)
EXPECT_EQ(true, _m->hasKey(keysB[i])) << keysB[i] <<": test1 + test3";
}
TEST_F(ConfigurationManagerTest, HasKeySubtable) {
_m->loadConfiguration(_configuration1);
const bool tSuccess = _m->hasKey("t");
ASSERT_EQ(true, tSuccess) << "t";
const bool tsSuccess = _m->hasKey("t.s");
EXPECT_EQ(false, tsSuccess) << "t.s";
const bool sSuccess = _m->hasKey("s");
EXPECT_EQ(false, sSuccess) << "s";
const bool sxSuccess = _m->hasKey("s.x");
EXPECT_EQ(false, sxSuccess) << "s.x";
}
TEST_F(ConfigurationManagerTest, HasKeyTypes) {
_m->setValue("t", ghoul::Dictionary());
_m->setValue("t.bool", bool(1));
_m->setValue("t.char", char(1));
_m->setValue("t.unsignedchar", (unsigned char)(1));
_m->setValue("t.signedchar", (signed char)(1));
_m->setValue("t.wchar", wchar_t(1));
_m->setValue("t.short", short(1));
_m->setValue("t.unsignedshort", (unsigned short)(1));
_m->setValue("t.int", int(1));
_m->setValue("t.unsignedint", (unsigned int)(1));
_m->setValue("t.long", long(1));
_m->setValue("t.unsignedlong", (unsigned long)(1));
_m->setValue("t.longlong", (long long)(1));
_m->setValue("t.unsignedlonglong", (unsigned long long)(1));
_m->setValue("t.float", float(1));
_m->setValue("t.double", double(1));
_m->setValue("t.longdouble", (long double)(1));
_m->setValue("t.string", "1");
bool success = _m->hasKey("t.bool");
EXPECT_EQ(true, success) << "t.bool";
success = _m->hasKey("t.char");
EXPECT_EQ(true, success) << "t.char";
success = _m->hasKey("t.unsignedchar");
EXPECT_EQ(true, success) << "t.unsignedchar";
success = _m->hasKey("t.signedchar");
EXPECT_EQ(true, success) << "t.signedchar";
success = _m->hasKey("t.wchar");
EXPECT_EQ(true, success) << "t.wchar";
success = _m->hasKey("t.short");
EXPECT_EQ(true, success) << "t.short";
success = _m->hasKey("t.unsignedshort");
EXPECT_EQ(true, success) << "t.unsignedshort";
success = _m->hasKey("t.int");
EXPECT_EQ(true, success) << "t.int";
success = _m->hasKey("t.unsignedint");
EXPECT_EQ(true, success) << "t.unsignedint";
success = _m->hasKey("t.long");
EXPECT_EQ(true, success) << "t.long";
success = _m->hasKey("t.unsignedlong");
EXPECT_EQ(true, success) << "t.unsignedlong";
success = _m->hasKey("t.longlong");
EXPECT_EQ(true, success) << "t.longlong";
success = _m->hasKey("t.unsignedlonglong");
EXPECT_EQ(true, success) << "t.unsignedlonglong";
success = _m->hasKey("t.float");
EXPECT_EQ(true, success) << "t.float";
success = _m->hasKey("t.double");
EXPECT_EQ(true, success) << "t.double";
success = _m->hasKey("t.longdouble");
EXPECT_EQ(true, success) << "t.longdouble";
success = _m->hasKey("t.string");
EXPECT_EQ(true, success) << "t.string";
}
TEST_F(ConfigurationManagerTest, GetValueFunction) {
std::string test;
bool success = _m->getValue("key", test);
EXPECT_EQ(false, success) << "Empty configuration";
success = _m->getValue("key.key", test);
EXPECT_EQ(false, success) << "Empty configuration recursive";
_m->loadConfiguration(_configuration1);
_m->loadConfiguration(_configuration3);
int testInt;
success = _m->getValue("t", testInt);
EXPECT_EQ(true, success) << "test1+test3 (t)";
EXPECT_EQ(1, testInt) << "test1+test3 (t)";
success = _m->getValue("s.a", test);
EXPECT_EQ(false, success) << "test1+test3 (s.a)";
success = _m->getValue("s.1", test);
EXPECT_EQ(true, success) << "test1+test3 (s.1)";
success = _m->getValue("s.1.a", test);
EXPECT_EQ(false, success) << "test1+test3 (s.1.a)";
success = _m->getValue("s.3.a", test);
EXPECT_EQ(true, success) << "test1+test3 (s.3.a)";
std::vector<int> testVec;
success = _m->getValue("key", testVec);
EXPECT_EQ(false, success) << "test1+test3: Vector access";
}
template <class T>
void correctnessHelperGetValue(ghoul::ConfigurationManager* m, const std::string& key) {
T value = T(0);
const bool success = m->getValue(key, value);
EXPECT_EQ(true, success) << "Type: " << typeid(T).name();
EXPECT_EQ(T(1), value) << "Type: " << typeid(T).name();
}
TEST_F(ConfigurationManagerTest, GetValueCorrectness) {
_m->loadConfiguration(_configuration1);
correctnessHelperGetValue<bool>(_m, "t");
correctnessHelperGetValue<char>(_m, "t");
correctnessHelperGetValue<signed char>(_m, "t");
correctnessHelperGetValue<unsigned char>(_m, "t");
correctnessHelperGetValue<wchar_t>(_m, "t");
correctnessHelperGetValue<short>(_m, "t");
correctnessHelperGetValue<unsigned short>(_m, "t");
correctnessHelperGetValue<int>(_m, "t");
correctnessHelperGetValue<unsigned int>(_m, "t");
correctnessHelperGetValue<long>(_m, "t");
correctnessHelperGetValue<unsigned long>(_m, "t");
correctnessHelperGetValue<long long>(_m, "t");
correctnessHelperGetValue<unsigned long long>(_m, "t");
correctnessHelperGetValue<float>(_m, "t");
correctnessHelperGetValue<double>(_m, "t");
correctnessHelperGetValue<long double>(_m, "t");
std::string value;
const bool success = _m->getValue("t", value);
EXPECT_EQ(true, success) << "Type: " << typeid(std::string).name();
EXPECT_STREQ("1", value.c_str()) << "Type: " << typeid(std::string).name();
}
TEST_F(ConfigurationManagerTest, SetValueRecursive) {
_m->setValue("t.a.b.c", 1);
EXPECT_EQ(true, _m->hasKey("t"));
EXPECT_EQ(true, _m->hasKey("t.a"));
EXPECT_EQ(true, _m->hasKey("t.a.b"));
EXPECT_EQ(true, _m->hasKey("t.a.b.c"));
}
TEST_F(ConfigurationManagerTest, SetValueCorrectness) {
_m->setValue("t.bool", bool(1));
_m->setValue("t.char", char(1));
_m->setValue("t.unsignedchar", (unsigned char)(1));
_m->setValue("t.signedchar", (signed char)(1));
_m->setValue("t.wchar", wchar_t(1));
_m->setValue("t.short", short(1));
_m->setValue("t.unsignedshort", (unsigned short)(1));
_m->setValue("t.int", int(1));
_m->setValue("t.unsignedint", (unsigned int)(1));
_m->setValue("t.long", long(1));
_m->setValue("t.unsignedlong", (unsigned long)(1));
_m->setValue("t.longlong", (long long)(1));
_m->setValue("t.unsignedlonglong", (unsigned long long)(1));
_m->setValue("t.float", float(1));
_m->setValue("t.double", double(1));
_m->setValue("t.longdouble", (long double)(1));
_m->setValue("t.string", "1");
correctnessHelperGetValue<bool>(_m, "t.bool");
correctnessHelperGetValue<char>(_m, "t.char");
correctnessHelperGetValue<signed char>(_m, "t.unsignedchar");
correctnessHelperGetValue<unsigned char>(_m, "t.signedchar");
correctnessHelperGetValue<wchar_t>(_m, "t.wchar");
correctnessHelperGetValue<short>(_m, "t.short");
correctnessHelperGetValue<unsigned short>(_m, "t.unsignedshort");
correctnessHelperGetValue<int>(_m, "t.int");
correctnessHelperGetValue<unsigned int>(_m, "t.unsignedint");
correctnessHelperGetValue<long>(_m, "t.long");
correctnessHelperGetValue<unsigned long>(_m, "t.unsignedlong");
correctnessHelperGetValue<long long>(_m, "t.longlong");
correctnessHelperGetValue<unsigned long long>(_m, "t.unsignedlonglong");
correctnessHelperGetValue<float>(_m, "t.float");
correctnessHelperGetValue<double>(_m, "t.double");
correctnessHelperGetValue<long double>(_m, "t.longdouble");
std::string value;
const bool success = _m->getValue("t.string", value);
EXPECT_EQ(true, success) << "Type: " << typeid(std::string).name();
EXPECT_STREQ("1", value.c_str()) << "Type: " << typeid(std::string).name();
}
TEST_F(ConfigurationManagerTest, SetValueOverridesConfiguration) {
_m->loadConfiguration(_configuration1);
int v = 0;
bool success = _m->getValue<int>("t", v);
ASSERT_EQ(true, success) << "t";
ASSERT_EQ(1, v) << "t";
_m->setValue("t", int(2));
success = _m->getValue<int>("t", v);
ASSERT_EQ(true, success) << "t";
ASSERT_EQ(2, v) << "t";
}
TEST_F(ConfigurationManagerTest, GetValueConversions) {
// converting from 1 -> all types is done in GetValueCorrectness
_m->loadConfiguration(_configuration2);
correctnessHelperGetValue<bool>(_m, "s.a1");
correctnessHelperGetValue<char>(_m, "s.a1");
correctnessHelperGetValue<signed char>(_m, "s.a1");
correctnessHelperGetValue<unsigned char>(_m, "s.a1");
correctnessHelperGetValue<wchar_t>(_m, "s.a1");
correctnessHelperGetValue<short>(_m, "s.a1");
correctnessHelperGetValue<unsigned short>(_m, "s.a1");
correctnessHelperGetValue<int>(_m, "s.a1");
correctnessHelperGetValue<unsigned int>(_m, "s.a1");
correctnessHelperGetValue<long>(_m, "s.a1");
correctnessHelperGetValue<unsigned long>(_m, "s.a1");
correctnessHelperGetValue<long long>(_m, "s.a1");
correctnessHelperGetValue<unsigned long long>(_m, "s.a1");
correctnessHelperGetValue<float>(_m, "s.a1");
correctnessHelperGetValue<double>(_m, "s.a1");
correctnessHelperGetValue<long double>(_m, "s.a1");
std::string value;
const bool success = _m->getValue("s.a1", value);
EXPECT_EQ(true, success) << "Type: " << typeid(std::string).name();
EXPECT_STREQ("1", value.c_str()) << "Type: " << typeid(std::string).name();
}
TEST_F(ConfigurationManagerTest, StringKeyVsIntKey) {
_m->loadConfiguration(_configuration3);
int v = 0;
bool success = _m->getValue("tt[\"1\"]", v);
ASSERT_EQ(true, success) << "tt.1";
EXPECT_EQ(2, v) << "tt.1";
success = _m->getValue("tt[1]", v);
ASSERT_EQ(true, success) << "tt[1]";
EXPECT_EQ(1, v) << "tt[1]";
}
TEST_F(ConfigurationManagerTest, InvalidKeyAccessInvariant) {
// Accessing an invalid key should not change the tested argument
std::mt19937 rd;
{
std::uniform_int_distribution<int> dist;
for (int i = 0; i < 10; ++i) {
const int testValue = dist(rd);
int test = testValue;
_m->getValue("key", test);
ASSERT_EQ(testValue, test) << "invariant int";
}
}
{
std::uniform_real_distribution<float> dist;
for (int i = 0; i < 10; ++i) {
const float testValue = dist(rd);
float test = testValue;
_m->getValue("key", test);
ASSERT_EQ(testValue, test) << "invariant float";
}
}
}
TEST_F(ConfigurationManagerTest, HasKeyFunction) {
bool success = _m->hasKey("key");
EXPECT_EQ(false, success) << "empty configuration";
_m->loadConfiguration(_configuration1);
success = _m->hasKey("t");
EXPECT_EQ(true, success) << "test1 (t)";
success = _m->hasKey("s");
EXPECT_EQ(false, success) << "test1 (s)";
_m->loadConfiguration(_configuration2);
success = _m->hasKey("s.a");
EXPECT_EQ(true, success) << "test1+test2 (s.a)";
success = _m->hasKey("s.c");
EXPECT_EQ(false, success) << "test1+test2 (s.c)";
}
TEST_F(ConfigurationManagerTest, MultipleKeyLoadOverwrite) {
_m->loadConfiguration(_configuration1);
int value;
_m->getValue("t", value);
EXPECT_EQ(1, value);
_m->loadConfiguration(_configuration2);
// configuration2 should overwrite the value t in configuration1
_m->getValue("t", value);
EXPECT_EQ(2, value);
}
template <class T>
void vectorClassHelper(ghoul::ConfigurationManager* m, const std::string& key) {
T value = T(0);
const bool success = m->getValue(key, value);
EXPECT_EQ(true, success) << "Type: " << typeid(T).name() << " | Key: " << key;
EXPECT_EQ(T(glm::vec4(5, 6, 7, 8)), value) << "Type: " << typeid(T).name() <<
" | Key: " << key;
}
template <>
void vectorClassHelper<glm::bvec2>(ghoul::ConfigurationManager* m, const std::string& key) {
glm::bvec2 value = glm::bvec2(false);
const bool success = m->getValue(key, value);
EXPECT_EQ(true, success) << "Type: bvec2 | Key: " << key;
EXPECT_EQ(true, value.x) << "Type: bvec2 | Key: " << key;
EXPECT_EQ(true, value.y) << "Type: bvec2 | Key: " << key;
}
template <>
void vectorClassHelper<glm::bvec3>(ghoul::ConfigurationManager* m, const std::string& key) {
glm::bvec3 value = glm::bvec3(false);
const bool success = m->getValue(key, value);
EXPECT_EQ(true, success) << "Type: bvec3 | Key: " << key;
EXPECT_EQ(true, value.x) << "Type: bvec3 | Key: " << key;
EXPECT_EQ(true, value.y) << "Type: bvec3 | Key: " << key;
EXPECT_EQ(true, value.z) << "Type: bvec3 | Key: " << key;
}
template <>
void vectorClassHelper<glm::bvec4>(ghoul::ConfigurationManager* m, const std::string& key) {
glm::bvec4 value = glm::bvec4(false);
const bool success = m->getValue(key, value);
EXPECT_EQ(true, success) << "Type: bvec4 | Key: " << key;
EXPECT_EQ(true, value.x) << "Type: bvec4 | Key: " << key;
EXPECT_EQ(true, value.y) << "Type: bvec4 | Key: " << key;
EXPECT_EQ(true, value.z) << "Type: bvec4 | Key: " << key;
EXPECT_EQ(true, value.w) << "Type: bvec4 | Key: " << key;
}
TEST_F(ConfigurationManagerTest, VectorClassesGet) {
_m->loadConfiguration(_configuration5);
vectorClassHelper<glm::vec2>(_m, "n2");
vectorClassHelper<glm::vec2>(_m, "num2");
vectorClassHelper<glm::vec2>(_m, "xy");
vectorClassHelper<glm::vec2>(_m, "rg");
vectorClassHelper<glm::vec2>(_m, "st");
vectorClassHelper<glm::dvec2>(_m, "n2");
vectorClassHelper<glm::dvec2>(_m, "num2");
vectorClassHelper<glm::dvec2>(_m, "xy");
vectorClassHelper<glm::dvec2>(_m, "rg");
vectorClassHelper<glm::dvec2>(_m, "st");
vectorClassHelper<glm::ivec2>(_m, "n2");
vectorClassHelper<glm::ivec2>(_m, "num2");
vectorClassHelper<glm::ivec2>(_m, "xy");
vectorClassHelper<glm::ivec2>(_m, "rg");
vectorClassHelper<glm::ivec2>(_m, "st");
vectorClassHelper<glm::uvec2>(_m, "n2");
vectorClassHelper<glm::uvec2>(_m, "num2");
vectorClassHelper<glm::uvec2>(_m, "xy");
vectorClassHelper<glm::uvec2>(_m, "rg");
vectorClassHelper<glm::uvec2>(_m, "st");
vectorClassHelper<glm::bvec2>(_m, "n2");
vectorClassHelper<glm::bvec2>(_m, "num2");
vectorClassHelper<glm::bvec2>(_m, "xy");
vectorClassHelper<glm::bvec2>(_m, "rg");
vectorClassHelper<glm::bvec2>(_m, "st");
vectorClassHelper<glm::vec3>(_m, "n3");
vectorClassHelper<glm::vec3>(_m, "num3");
vectorClassHelper<glm::vec3>(_m, "xyz");
vectorClassHelper<glm::vec3>(_m, "rgb");
vectorClassHelper<glm::vec3>(_m, "stp");
vectorClassHelper<glm::dvec3>(_m, "n3");
vectorClassHelper<glm::dvec3>(_m, "num3");
vectorClassHelper<glm::dvec3>(_m, "xyz");
vectorClassHelper<glm::dvec3>(_m, "rgb");
vectorClassHelper<glm::dvec3>(_m, "stp");
vectorClassHelper<glm::ivec3>(_m, "n3");
vectorClassHelper<glm::ivec3>(_m, "num3");
vectorClassHelper<glm::ivec3>(_m, "xyz");
vectorClassHelper<glm::ivec3>(_m, "rgb");
vectorClassHelper<glm::ivec3>(_m, "stp");
vectorClassHelper<glm::uvec3>(_m, "n3");
vectorClassHelper<glm::uvec3>(_m, "num3");
vectorClassHelper<glm::uvec3>(_m, "xyz");
vectorClassHelper<glm::uvec3>(_m, "rgb");
vectorClassHelper<glm::uvec3>(_m, "stp");
vectorClassHelper<glm::bvec3>(_m, "n3");
vectorClassHelper<glm::bvec3>(_m, "num3");
vectorClassHelper<glm::bvec3>(_m, "xyz");
vectorClassHelper<glm::bvec3>(_m, "rgb");
vectorClassHelper<glm::bvec3>(_m, "stp");
vectorClassHelper<glm::vec4>(_m, "n4");
vectorClassHelper<glm::vec4>(_m, "num4");
vectorClassHelper<glm::vec4>(_m, "xyzw");
vectorClassHelper<glm::vec4>(_m, "rgba");
vectorClassHelper<glm::vec4>(_m, "stpq");
vectorClassHelper<glm::dvec4>(_m, "n4");
vectorClassHelper<glm::dvec4>(_m, "num4");
vectorClassHelper<glm::dvec4>(_m, "xyzw");
vectorClassHelper<glm::dvec4>(_m, "rgba");
vectorClassHelper<glm::dvec4>(_m, "stpq");
vectorClassHelper<glm::ivec4>(_m, "num4");
vectorClassHelper<glm::ivec4>(_m, "n4");
vectorClassHelper<glm::ivec4>(_m, "xyzw");
vectorClassHelper<glm::ivec4>(_m, "rgba");
vectorClassHelper<glm::ivec4>(_m, "stpq");
vectorClassHelper<glm::uvec4>(_m, "num4");
vectorClassHelper<glm::uvec4>(_m, "n4");
vectorClassHelper<glm::uvec4>(_m, "xyzw");
vectorClassHelper<glm::uvec4>(_m, "rgba");
vectorClassHelper<glm::uvec4>(_m, "stpq");
vectorClassHelper<glm::bvec4>(_m, "num4");
vectorClassHelper<glm::bvec4>(_m, "n4");
vectorClassHelper<glm::bvec4>(_m, "xyzw");
vectorClassHelper<glm::bvec4>(_m, "rgba");
vectorClassHelper<glm::bvec4>(_m, "stpq");
glm::vec3 value = glm::vec3(0.f);
const bool success = _m->getValue("mix", value);
EXPECT_EQ(false, success) << "Type: mixed";
EXPECT_EQ(glm::vec3(0.f), value) << "Type: mixed";
}
TEST_F(ConfigurationManagerTest, VectorClassesSet) {
_m->setValue("t.vec2", glm::vec2(5,6));
_m->setValue("t.vec3", glm::vec3(5,6,7));
_m->setValue("t.vec4", glm::vec4(5,6,7,8));
_m->setValue("t.dvec2", glm::dvec2(5,6));
_m->setValue("t.dvec3", glm::dvec3(5,6,7));
_m->setValue("t.dvec4", glm::dvec4(5,6,7,8));
_m->setValue("t.ivec2", glm::ivec2(5,6));
_m->setValue("t.ivec3", glm::ivec3(5,6,7));
_m->setValue("t.ivec4", glm::ivec4(5,6,7,8));
_m->setValue("t.uvec2", glm::uvec2(5,6));
_m->setValue("t.uvec3", glm::uvec3(5,6,7));
_m->setValue("t.uvec4", glm::uvec4(5,6,7,8));
_m->setValue("t.bvec2", glm::bvec2(true));
_m->setValue("t.bvec3", glm::bvec3(true));
_m->setValue("t.bvec4", glm::bvec4(true));
vectorClassHelper<glm::vec2>(_m, "t.vec2");
vectorClassHelper<glm::vec3>(_m, "t.vec3");
vectorClassHelper<glm::vec4>(_m, "t.vec4");
vectorClassHelper<glm::dvec2>(_m, "t.dvec2");
vectorClassHelper<glm::dvec3>(_m, "t.dvec3");
vectorClassHelper<glm::dvec4>(_m, "t.dvec4");
vectorClassHelper<glm::ivec2>(_m, "t.ivec2");
vectorClassHelper<glm::ivec3>(_m, "t.ivec3");
vectorClassHelper<glm::ivec4>(_m, "t.ivec4");
vectorClassHelper<glm::uvec2>(_m, "t.uvec2");
vectorClassHelper<glm::uvec3>(_m, "t.uvec3");
vectorClassHelper<glm::uvec4>(_m, "t.uvec4");
vectorClassHelper<glm::bvec2>(_m, "t.bvec2");
vectorClassHelper<glm::bvec3>(_m, "t.bvec3");
vectorClassHelper<glm::bvec4>(_m, "t.bvec4");
}
template <class T, typename U>
void matrixClassHelper(ghoul::ConfigurationManager* m, const std::string& key) {
T value = T(0);
const bool success = m->getValue(key, value);
EXPECT_EQ(success, true) << "Type: " << typeid(T).name();
const glm::detail::tmat4x4<U> res4 = glm::detail::tmat4x4<U>(
5.0, 6.0, 7.0, 8.0,
9.0, 10.0,11.0,12.0,
13.0,14.0,15.0,16.0,
17.0,18.0,19.0,20.0
);
const T res = T(res4);
EXPECT_EQ(res, value) << "Type: " << typeid(T).name();
}
TEST_F(ConfigurationManagerTest, MatrixClassesGet) {
_m->loadConfiguration(_configuration5);
matrixClassHelper<glm::mat2x2, float>(_m, "m2x2");
matrixClassHelper<glm::mat2x3, float>(_m, "m2x3");
matrixClassHelper<glm::mat2x4, float>(_m, "m2x4");
matrixClassHelper<glm::mat3x2, float>(_m, "m3x2");
matrixClassHelper<glm::mat3x3, float>(_m, "m3x3");
matrixClassHelper<glm::mat3x4, float>(_m, "m3x4");
matrixClassHelper<glm::mat4x2, float>(_m, "m4x2");
matrixClassHelper<glm::mat4x3, float>(_m, "m4x3");
matrixClassHelper<glm::mat4x4, float>(_m, "m4x4");
matrixClassHelper<glm::dmat2x2, double>(_m, "m2x2");
matrixClassHelper<glm::dmat2x3, double>(_m, "m2x3");
matrixClassHelper<glm::dmat2x4, double>(_m, "m2x4");
matrixClassHelper<glm::dmat3x2, double>(_m, "m3x2");
matrixClassHelper<glm::dmat3x3, double>(_m, "m3x3");
matrixClassHelper<glm::dmat3x4, double>(_m, "m3x4");
matrixClassHelper<glm::dmat4x2, double>(_m, "m4x2");
matrixClassHelper<glm::dmat4x3, double>(_m, "m4x3");
matrixClassHelper<glm::dmat4x4, double>(_m, "m4x4");
}
TEST_F(ConfigurationManagerTest, MatrixClassSet) {
_m->setValue("f.m2x2", glm::mat2x2(5, 6, 9, 10));
_m->setValue("f.m2x3", glm::mat2x3(5, 6, 7, 9, 10, 11));
_m->setValue("f.m2x4", glm::mat2x4(5, 6, 7, 8, 9, 10, 11, 12));
_m->setValue("f.m3x2", glm::mat3x2(5, 6, 9, 10, 13, 14));
_m->setValue("f.m3x3", glm::mat3x3(5, 6, 7, 9, 10, 11, 13, 14, 15));
_m->setValue("f.m3x4", glm::mat3x4(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16));
_m->setValue("f.m4x2", glm::mat4x2(5, 6, 9, 10, 13, 14, 17, 18));
_m->setValue("f.m4x3", glm::mat4x3(5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18, 19));
_m->setValue("f.m4x4", glm::mat4x4(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20));
matrixClassHelper<glm::mat2x2, float>(_m, "f.m2x2");
matrixClassHelper<glm::mat2x3, float>(_m, "f.m2x3");
matrixClassHelper<glm::mat2x4, float>(_m, "f.m2x4");
matrixClassHelper<glm::mat3x2, float>(_m, "f.m3x2");
matrixClassHelper<glm::mat3x3, float>(_m, "f.m3x3");
matrixClassHelper<glm::mat3x4, float>(_m, "f.m3x4");
matrixClassHelper<glm::mat4x2, float>(_m, "f.m4x2");
matrixClassHelper<glm::mat4x3, float>(_m, "f.m4x3");
matrixClassHelper<glm::mat4x4, float>(_m, "f.m4x4");
_m->setValue("d.m2x2", glm::dmat2x2(5, 6, 9, 10));
_m->setValue("d.m2x3", glm::dmat2x3(5, 6, 7, 9, 10, 11));
_m->setValue("d.m2x4", glm::dmat2x4(5, 6, 7, 8, 9, 10, 11, 12));
_m->setValue("d.m3x2", glm::dmat3x2(5, 6, 9, 10, 13, 14));
_m->setValue("d.m3x3", glm::dmat3x3(5, 6, 7, 9, 10, 11, 13, 14, 15));
_m->setValue("d.m3x4", glm::dmat3x4(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16));
_m->setValue("d.m4x2", glm::dmat4x2(5, 6, 9, 10, 13, 14, 17, 18));
_m->setValue("d.m4x3", glm::dmat4x3(5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18, 19));
_m->setValue("d.m4x4", glm::dmat4x4(
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16,
17, 18, 19, 20));
matrixClassHelper<glm::dmat2x2, double>(_m, "d.m2x2");
matrixClassHelper<glm::dmat2x3, double>(_m, "d.m2x3");
matrixClassHelper<glm::dmat2x4, double>(_m, "d.m2x4");
matrixClassHelper<glm::dmat3x2, double>(_m, "d.m3x2");
matrixClassHelper<glm::dmat3x3, double>(_m, "d.m3x3");
matrixClassHelper<glm::dmat3x4, double>(_m, "d.m3x4");
matrixClassHelper<glm::dmat4x2, double>(_m, "d.m4x2");
matrixClassHelper<glm::dmat4x3, double>(_m, "d.m4x3");
matrixClassHelper<glm::dmat4x4, double>(_m, "d.m4x4");
}