/*
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 .
*/
#include
#include
#include
#include
#include
#include
namespace ousia {
static void assertBoolConversion(Variant conv, Variant expected,
bool expectedSuccess,
VariantConverter::Mode mode, Logger &logger)
{
EXPECT_EQ(expectedSuccess, VariantConverter::toBool(conv, logger, mode));
if (expectedSuccess) {
EXPECT_EQ(expected, conv);
}
}
TEST(VariantConverter, toBool)
{
// setup
Logger logger;
Variant n = nullptr;
Variant b = true;
Variant i = 0;
Variant d = 2.3;
Variant s = "test";
Variant A = Variant::arrayType{b, i, d, s};
Variant M = Variant::mapType{{"b", b}, {"i", i}, {"d", d}, {"s", s}};
Variant::cardinalityType card;
card.merge({2, 5});
Variant C = card;
// in safe mode only bool to bool conversion should be possible.
assertBoolConversion(n, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertBoolConversion(b, b, true, VariantConverter::Mode::SAFE, logger);
assertBoolConversion(i, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertBoolConversion(d, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertBoolConversion(s, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertBoolConversion(A, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertBoolConversion(M, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertBoolConversion(C, nullptr, false, VariantConverter::Mode::SAFE,
logger);
// in all mode more should be possible.
assertBoolConversion(n, false, true, VariantConverter::Mode::ALL, logger);
assertBoolConversion(b, b, true, VariantConverter::Mode::ALL, logger);
assertBoolConversion(i, false, true, VariantConverter::Mode::ALL, logger);
assertBoolConversion(d, true, true, VariantConverter::Mode::ALL, logger);
// it may be counter-intuitive at first, but everything else gets just
// converted to true.
assertBoolConversion(s, true, true, VariantConverter::Mode::ALL, logger);
assertBoolConversion(A, true, true, VariantConverter::Mode::ALL, logger);
assertBoolConversion(M, true, true, VariantConverter::Mode::ALL, logger);
assertBoolConversion(C, true, true, VariantConverter::Mode::ALL, logger);
}
static void assertIntConversion(Variant conv, Variant expected,
bool expectedSuccess,
VariantConverter::Mode mode, Logger &logger)
{
EXPECT_EQ(expectedSuccess, VariantConverter::toInt(conv, logger, mode));
if (expectedSuccess) {
EXPECT_EQ(expected, conv);
}
}
TEST(VariantConverter, toInt)
{
// setup
Logger logger;
Variant n = nullptr;
Variant b = true;
Variant i = 6;
Variant d = 2.7;
Variant s = "test";
Variant A = Variant::arrayType{i};
Variant M = Variant::mapType{{"b", b}, {"i", i}, {"d", d}, {"s", s}};
Variant::cardinalityType card;
card.merge({4});
Variant C = card;
// in safe mode only int to int conversion should be possible.
assertIntConversion(n, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertIntConversion(b, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertIntConversion(i, i, true, VariantConverter::Mode::SAFE, logger);
assertIntConversion(d, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertIntConversion(s, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertIntConversion(A, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertIntConversion(M, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertIntConversion(C, nullptr, false, VariantConverter::Mode::SAFE,
logger);
// in all mode more should be possible.
assertIntConversion(n, 0, true, VariantConverter::Mode::ALL, logger);
assertIntConversion(b, 1, true, VariantConverter::Mode::ALL, logger);
assertIntConversion(i, i, true, VariantConverter::Mode::ALL, logger);
assertIntConversion(d, 2, true, VariantConverter::Mode::ALL, logger);
assertIntConversion(s, nullptr, false, VariantConverter::Mode::ALL, logger);
assertIntConversion(A, i, true, VariantConverter::Mode::ALL, logger);
assertIntConversion(M, nullptr, false, VariantConverter::Mode::ALL, logger);
assertIntConversion(C, 4, true, VariantConverter::Mode::ALL, logger);
}
static void assertDoubleConversion(Variant conv, Variant expected,
bool expectedSuccess,
VariantConverter::Mode mode, Logger &logger)
{
EXPECT_EQ(expectedSuccess, VariantConverter::toDouble(conv, logger, mode));
if (expectedSuccess) {
EXPECT_EQ(expected, conv);
}
}
TEST(VariantConverter, toDouble)
{
// setup
Logger logger;
Variant n = nullptr;
Variant b = true;
Variant i = 6;
Variant d = 2.7;
Variant s = "test";
Variant A = Variant::arrayType{d};
Variant M = Variant::mapType{{"b", b}, {"i", i}, {"d", d}, {"s", s}};
Variant::cardinalityType card;
card.merge({4});
Variant C = card;
// in safe mode only int to double and double to double conversion should be
// possible.
assertDoubleConversion(n, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertDoubleConversion(b, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertDoubleConversion(i, 6.0, true, VariantConverter::Mode::SAFE, logger);
assertDoubleConversion(d, d, true, VariantConverter::Mode::SAFE, logger);
assertDoubleConversion(s, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertDoubleConversion(A, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertDoubleConversion(M, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertDoubleConversion(C, nullptr, false, VariantConverter::Mode::SAFE,
logger);
// in all mode more should be possible.
assertDoubleConversion(n, 0.0, true, VariantConverter::Mode::ALL, logger);
assertDoubleConversion(b, 1.0, true, VariantConverter::Mode::ALL, logger);
assertDoubleConversion(i, 6.0, true, VariantConverter::Mode::ALL, logger);
assertDoubleConversion(d, d, true, VariantConverter::Mode::ALL, logger);
assertDoubleConversion(s, nullptr, false, VariantConverter::Mode::ALL,
logger);
assertDoubleConversion(A, d, true, VariantConverter::Mode::ALL, logger);
assertDoubleConversion(M, nullptr, false, VariantConverter::Mode::ALL,
logger);
assertDoubleConversion(C, 4.0, true, VariantConverter::Mode::ALL, logger);
}
static void assertStringConversion(Variant conv, Variant expected,
bool expectedSuccess,
VariantConverter::Mode mode, Logger &logger)
{
EXPECT_EQ(expectedSuccess, VariantConverter::toString(conv, logger, mode));
if (expectedSuccess) {
EXPECT_EQ(expected, conv);
}
}
TEST(VariantConverter, toString)
{
// setup
Logger logger;
Variant n = nullptr;
Variant b = true;
Variant i = 6;
Variant d = 2.7;
Variant s = "test";
Variant A = Variant::arrayType{b, i, d, s};
Variant M = Variant::mapType{{"b", b}, {"i", i}, {"d", d}, {"s", s}};
Variant::cardinalityType card;
card.merge({2, 4});
card.merge(Variant::rangeType::typeRangeFrom(7));
Variant C = card;
// in safe mode only primitive types should be converted to strings.
assertStringConversion(n, "null", true, VariantConverter::Mode::SAFE,
logger);
assertStringConversion(b, "true", true, VariantConverter::Mode::SAFE,
logger);
assertStringConversion(i, "6", true, VariantConverter::Mode::SAFE, logger);
assertStringConversion(d, "2.7", true, VariantConverter::Mode::SAFE,
logger);
assertStringConversion(s, s, true, VariantConverter::Mode::SAFE, logger);
assertStringConversion(A, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertStringConversion(M, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertStringConversion(C, nullptr, false, VariantConverter::Mode::SAFE,
logger);
// in all mode more should be possible.
assertStringConversion(n, "null", true, VariantConverter::Mode::ALL,
logger);
assertStringConversion(b, "true", true, VariantConverter::Mode::ALL,
logger);
assertStringConversion(i, "6", true, VariantConverter::Mode::ALL, logger);
assertStringConversion(d, "2.7", true, VariantConverter::Mode::ALL, logger);
assertStringConversion(s, s, true, VariantConverter::Mode::ALL, logger);
assertStringConversion(A, "[true,6,2.7,\"test\"]", true,
VariantConverter::Mode::ALL, logger);
assertStringConversion(M, "{\"b\":true,\"d\":2.7,\"i\":6,\"s\":\"test\"}",
true, VariantConverter::Mode::ALL, logger);
assertStringConversion(C, "{2-4, >6}", true,
VariantConverter::Mode::ALL, logger);
}
static void assertArrayConversion(Variant conv, Variant expected,
bool expectedSuccess, const Rtti *innerType,
VariantConverter::Mode mode, Logger &logger)
{
EXPECT_EQ(expectedSuccess,
VariantConverter::toArray(conv, innerType, logger, mode));
if (expectedSuccess) {
EXPECT_EQ(expected, conv);
}
}
TEST(VariantConverter, toArray)
{
// setup
Logger logger;
Variant n = nullptr;
Variant b = true;
Variant i = 6;
Variant d = 2.7;
Variant s = "9";
Variant A = Variant::arrayType{b, i, d, s};
Variant M = Variant::mapType{{"b", b}, {"i", i}, {"d", d}, {"s", s}};
Variant::cardinalityType card;
card.merge({2, 4});
card.merge(Variant::rangeType::typeRangeFrom(7));
Variant C = card;
// in safe mode only array to array conversion should be possible.
assertArrayConversion(n, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::SAFE, logger);
assertArrayConversion(b, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::SAFE, logger);
assertArrayConversion(i, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::SAFE, logger);
assertArrayConversion(d, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::SAFE, logger);
assertArrayConversion(s, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::SAFE, logger);
assertArrayConversion(A, A, true, &RttiTypes::None,
VariantConverter::Mode::SAFE, logger);
assertArrayConversion(M, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::SAFE, logger);
assertArrayConversion(C, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::SAFE, logger);
// in all mode more should be possible.
assertArrayConversion(n, Variant::arrayType{n}, true, &RttiTypes::None,
VariantConverter::Mode::ALL, logger);
assertArrayConversion(b, Variant::arrayType{b}, true, &RttiTypes::None,
VariantConverter::Mode::ALL, logger);
assertArrayConversion(i, Variant::arrayType{i}, true, &RttiTypes::None,
VariantConverter::Mode::ALL, logger);
assertArrayConversion(d, Variant::arrayType{d}, true, &RttiTypes::None,
VariantConverter::Mode::ALL, logger);
assertArrayConversion(s, Variant::arrayType{s}, true, &RttiTypes::None,
VariantConverter::Mode::ALL, logger);
assertArrayConversion(A, A, true, &RttiTypes::None,
VariantConverter::Mode::ALL, logger);
assertArrayConversion(M, Variant::arrayType{M}, true, &RttiTypes::None,
VariantConverter::Mode::ALL, logger);
assertArrayConversion(C, Variant::arrayType{C}, true, &RttiTypes::None,
VariantConverter::Mode::ALL, logger);
// as an example also check the inner type converion
assertArrayConversion(
A, Variant::arrayType{Variant(1), Variant(6), Variant(2), Variant(9)},
true, &RttiTypes::Int, VariantConverter::Mode::ALL, logger);
}
static void assertMapConversion(Variant conv, Variant expected,
bool expectedSuccess, const Rtti *innerType,
VariantConverter::Mode mode, Logger &logger)
{
EXPECT_EQ(expectedSuccess,
VariantConverter::toMap(conv, innerType, logger, mode));
if (expectedSuccess) {
EXPECT_EQ(expected, conv);
}
}
TEST(VariantConverter, toMap)
{
// setup
Logger logger;
Variant n = nullptr;
Variant b = true;
Variant i = 6;
Variant d = 2.7;
Variant s = "9";
Variant A = Variant::arrayType{b, i, d, s};
Variant M = Variant::mapType{{"b", b}, {"i", i}, {"d", d}, {"s", s}};
Variant::cardinalityType card;
card.merge({2, 4});
card.merge(Variant::rangeType::typeRangeFrom(7));
Variant C = card;
// in safe mode only map to map conversion should be possible.
assertMapConversion(n, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::SAFE, logger);
assertMapConversion(b, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::SAFE, logger);
assertMapConversion(i, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::SAFE, logger);
assertMapConversion(d, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::SAFE, logger);
assertMapConversion(s, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::SAFE, logger);
assertMapConversion(A, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::SAFE, logger);
assertMapConversion(M, M, true, &RttiTypes::None,
VariantConverter::Mode::SAFE, logger);
assertMapConversion(C, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::SAFE, logger);
// in all mode that should be the same.
assertMapConversion(n, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::ALL, logger);
assertMapConversion(b, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::ALL, logger);
assertMapConversion(i, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::ALL, logger);
assertMapConversion(d, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::ALL, logger);
assertMapConversion(s, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::ALL, logger);
assertMapConversion(A, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::ALL, logger);
assertMapConversion(M, M, true, &RttiTypes::None,
VariantConverter::Mode::ALL, logger);
assertMapConversion(C, nullptr, false, &RttiTypes::None,
VariantConverter::Mode::ALL, logger);
// but we should be able to convert the inner type.
assertMapConversion(M, Variant::mapType{{"b", Variant(1)},
{"i", Variant(6)},
{"d", Variant(2)},
{"s", Variant(9)}},
true, &RttiTypes::Int, VariantConverter::Mode::ALL,
logger);
// which should not work in SAFE mode.
assertMapConversion(M, Variant::mapType{{"b", Variant(1)},
{"i", Variant(6)},
{"d", Variant(2)},
{"s", Variant(9)}},
false, &RttiTypes::Int, VariantConverter::Mode::SAFE,
logger);
}
static void assertCardinalityConversion(Variant conv, Variant expected,
bool expectedSuccess,
VariantConverter::Mode mode,
Logger &logger)
{
EXPECT_EQ(expectedSuccess,
VariantConverter::toCardinality(conv, logger, mode));
if (expectedSuccess) {
EXPECT_EQ(expected, conv);
}
}
TEST(VariantConverter, toCardinality)
{
// setup
Logger logger;
Variant n = nullptr;
Variant b = true;
Variant i = 6;
Variant d = 2.7;
Variant s = "{2-3, >9}";
Variant A =
Variant::arrayType{Variant(2), Variant(7), Variant(10), Variant(10)};
Variant M = Variant::mapType{{"b", b}, {"i", i}, {"d", d}, {"s", s}};
Variant::cardinalityType card;
card.merge({2, 4});
card.merge(Variant::rangeType::typeRangeFrom(7));
Variant C = card;
// in safe mode only ints and cardinalities should be convertible.
assertCardinalityConversion(n, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertCardinalityConversion(b, nullptr, false, VariantConverter::Mode::SAFE,
logger);
{
Variant::cardinalityType expected;
expected.merge({6});
assertCardinalityConversion(i, expected, true,
VariantConverter::Mode::SAFE, logger);
}
assertCardinalityConversion(d, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertCardinalityConversion(s, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertCardinalityConversion(A, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertCardinalityConversion(M, nullptr, false, VariantConverter::Mode::SAFE,
logger);
assertCardinalityConversion(C, C, true, VariantConverter::Mode::SAFE,
logger);
// in all mode more should be possible.
assertCardinalityConversion(n, Variant::cardinalityType{}, true,
VariantConverter::Mode::ALL, logger);
{
Variant::cardinalityType expected;
expected.merge({Variant::rangeType::typeRange()});
assertCardinalityConversion(b, expected, true,
VariantConverter::Mode::ALL, logger);
}
{
Variant::cardinalityType expected;
expected.merge({6});
assertCardinalityConversion(i, expected, true,
VariantConverter::Mode::ALL, logger);
}
{
Variant::cardinalityType expected;
expected.merge({3});
assertCardinalityConversion(d, expected, true,
VariantConverter::Mode::ALL, logger);
}
{
Variant::cardinalityType expected;
expected.merge({2, 3});
expected.merge(Variant::rangeType::typeRangeFrom(10));
assertCardinalityConversion(s, expected, true,
VariantConverter::Mode::ALL, logger);
}
{
Variant::cardinalityType expected;
expected.merge({2, 7});
expected.merge({10});
assertCardinalityConversion(A, expected, true,
VariantConverter::Mode::ALL, logger);
}
// for Map we still have no conversion
assertCardinalityConversion(M, nullptr, false, VariantConverter::Mode::ALL,
logger);
assertCardinalityConversion(C, C, true, VariantConverter::Mode::ALL,
logger);
}
}