diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-13 23:44:40 +0100 |
---|---|---|
committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-13 23:44:40 +0100 |
commit | c5345f13b3d33630d3e3d0021f10945627ae6e2d (patch) | |
tree | e2464f0c638818034ca9fc937dfdc044d3d70cf3 /test | |
parent | df82b147b98cd09cb94f017910e400e148886fbe (diff) |
Added new Property class for defining getters and setters
Diffstat (limited to 'test')
-rw-r--r-- | test/core/common/PropertyTest.cpp | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/test/core/common/PropertyTest.cpp b/test/core/common/PropertyTest.cpp new file mode 100644 index 0000000..c28feeb --- /dev/null +++ b/test/core/common/PropertyTest.cpp @@ -0,0 +1,178 @@ +/* + Ousía + Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <gtest/gtest.h> + +#include <core/common/Rtti.hpp> +#include <core/common/Property.hpp> + +namespace ousia { + +namespace { +struct TestObject { + TestObject(int a) : a(a) {} + int a; + + static Variant getA(const TestObject *obj) { return Variant{obj->a}; } + + static void setA(const Variant &value, TestObject *obj) + { + if (value.isInt()) { + obj->a = value.asInt(); + } + } +}; +} + +static Variant getString(const TestObject *obj) { return "foo"; } + +TEST(Getter, construction) +{ + { + Getter<TestObject> getter{}; + ASSERT_FALSE(getter.isValid()); + } + + { + Getter<TestObject> getter{nullptr}; + ASSERT_FALSE(getter.isValid()); + } + + { + Getter<TestObject> getter{TestObject::getA}; + ASSERT_TRUE(getter.isValid()); + } +} + +TEST(Getter, validation) +{ + const PropertyType type{RttiTypes::Int}; + TestObject obj{123}; + + { + // No specifiy type set, strings can be returned + Getter<TestObject> getter{getString}; + ASSERT_EQ("foo", getter.get(&obj)); + } + + { + // Int type set, returning strings is an exception + Getter<TestObject> getter{getString}; + getter.propertyType = &type; + ASSERT_THROW(getter.get(&obj), LoggableException); + } + + { + Getter<TestObject> getter{TestObject::getA}; + + // Basic functionality + ASSERT_EQ(123, getter.call(Variant::arrayType{}, &obj)); + + // Exception should be thrown if an argument is explicitly given + ASSERT_THROW(getter.call(Variant::arrayType{1}, &obj), + PropertyException); + } +} + +TEST(Setter, construction) +{ + { + Setter<TestObject> setter{}; + ASSERT_FALSE(setter.isValid()); + } + + { + Setter<TestObject> setter{nullptr}; + ASSERT_FALSE(setter.isValid()); + } + + { + Setter<TestObject> setter{TestObject::setA}; + ASSERT_TRUE(setter.isValid()); + } +} + +TEST(Setter, validation) +{ + const PropertyType type{RttiTypes::Int}; + TestObject obj{123}; + + Setter<TestObject> setter{TestObject::setA}; + + // An exception should be thrown if not exactly one argument is passed to + // the setter + ASSERT_THROW(setter.call(Variant::arrayType{}, &obj), PropertyException); + ASSERT_THROW(setter.call(Variant::arrayType{1, 2}, &obj), + PropertyException); + + setter.call(Variant::arrayType{42}, &obj); // OK + ASSERT_EQ(42, obj.a); + + // No specifiy type set, any value can be given (does not crash because of + // explicity type check in the callback function, see above). + setter.set("foo", &obj); + ASSERT_EQ(42, obj.a); + + setter.propertyType = &type; + ASSERT_THROW(setter.set("foo", &obj), LoggableException); + + setter.set(123, &obj); + ASSERT_EQ(123, obj.a); +} + +TEST(Property, construction) +{ + TestObject obj{123}; + + { + ASSERT_THROW(Property<TestObject> property{nullptr}, PropertyException); + } + + { + Property<TestObject> property{TestObject::getA}; + ASSERT_TRUE(property.isReadonly()); + ASSERT_THROW(property.set(42, &obj), LoggableException); + } + + { + Property<TestObject> property{TestObject::getA, TestObject::setA}; + ASSERT_FALSE(property.isReadonly()); + ASSERT_EQ(123, property.get(&obj).asInt()); + + property.set(42, &obj); + ASSERT_EQ(42, property.get(&obj).asInt()); + + property.set("bla", &obj); + ASSERT_EQ(42, property.get(&obj).asInt()); + } + + { + Property<TestObject> property{RttiTypes::Int, TestObject::getA, + TestObject::setA}; + ASSERT_FALSE(property.isReadonly()); + + ASSERT_EQ(42, property.get(&obj).asInt()); + + property.set(123, &obj); + ASSERT_EQ(123, property.get(&obj).asInt()); + + ASSERT_THROW(property.set("bla", &obj), LoggableException); + } +} +} + |