#include "includes.h" #include "lexer_test.h" #include "../../../sdv_executables/sdv_idl_compiler/constvariant.cpp" using CConstVariantTest = CLexerTest; TEST_F(CConstVariantTest, DefaultConstruction) { CConstVariant var; EXPECT_EQ(var.Get(), 0); } TEST_F(CConstVariantTest, LiteralDirectValueConstruction) { EXPECT_EQ(CConstVariant(5).Get(), 5); EXPECT_EQ(CConstVariant(10u).Get(), 10u); EXPECT_EQ(CConstVariant(20l).Get(), static_cast(20l)); EXPECT_EQ(CConstVariant(static_cast(30ul)).Get(), 30ul); EXPECT_EQ(CConstVariant(40ll).Get(), 40ll); EXPECT_EQ(CConstVariant(50ull).Get(), 50ull); EXPECT_EQ(CConstVariant('A').Get(), 'A'); EXPECT_EQ(CConstVariant(L'B').Get(), L'B'); EXPECT_EQ(CConstVariant(u8'C').Get(), u8'C'); EXPECT_EQ(CConstVariant(u'D').Get(), u'D'); EXPECT_EQ(CConstVariant(U'E').Get(), U'E'); EXPECT_EQ(CConstVariant(true).Get(), true); EXPECT_EQ(CConstVariant(static_cast("string")).Get(), "string"); EXPECT_EQ(CConstVariant(static_cast(u8"string")).Get(), u8"string"); EXPECT_EQ(CConstVariant(static_cast(u"string")).Get(), u"string"); EXPECT_EQ(CConstVariant(static_cast(U"string")).Get(), U"string"); EXPECT_EQ(CConstVariant(static_cast(L"string")).Get(), L"string"); } TEST_F(CConstVariantTest, LiteralIndirectValueConstruction) { bool b = true; EXPECT_EQ(CConstVariant(b).Get(), true); int8_t i8 = 10; EXPECT_EQ(CConstVariant(i8).Get(), 10); int16_t i16 = 20; EXPECT_EQ(CConstVariant(i16).Get(), 20); int32_t i32 = 30; EXPECT_EQ(CConstVariant(i32).Get(), 30); int64_t i64 = 40; EXPECT_EQ(CConstVariant(i64).Get(), 40); uint8_t ui8 = 50; EXPECT_EQ(CConstVariant(ui8).Get(), 50); uint16_t ui16 = 60; EXPECT_EQ(CConstVariant(ui16).Get(), 60u); uint32_t ui32 = 70; EXPECT_EQ(CConstVariant(ui32).Get(), 70u); uint64_t ui64 = 80; EXPECT_EQ(CConstVariant(ui64).Get(), 80ull); float f = 90.0; EXPECT_EQ(CConstVariant(f).Get(), 90.0); double d = 100.0; EXPECT_EQ(CConstVariant(d).Get(), 100.0); long double ld = 110.0; EXPECT_EQ(CConstVariant(ld).Get(), 110.0); std::string ss = "string"; EXPECT_EQ(CConstVariant(ss).Get(), "string"); std::string ssUtf8 = u8"string"; EXPECT_EQ(CConstVariant(ssUtf8).Get(), u8"string"); std::u16string ssUtf16 = u"string"; EXPECT_EQ(CConstVariant(ssUtf16).Get(), u"string"); std::u32string ssUtf32 = U"string"; EXPECT_EQ(CConstVariant(ssUtf32).Get(), U"string"); std::wstring ssWide = L"string"; EXPECT_EQ(CConstVariant(ssWide).Get(), L"string"); } TEST_F(CConstVariantTest, LiteralDirectValueAssignment) { CConstVariant var; var = 5; EXPECT_EQ(var.Get(), 5); var = 10u; EXPECT_EQ(var.Get(), 10u); var = 20l; EXPECT_EQ(var.Get(), 20l); var = static_cast(30ul); EXPECT_EQ(var.Get(), 30ul); var = 40ll; EXPECT_EQ(var.Get(), 40ll); var = 50ull; EXPECT_EQ(var.Get(), 50ull); var = 'A'; EXPECT_EQ(var.Get(), 'A'); var = L'B'; EXPECT_EQ(var.Get(), L'B'); var = u8'C'; EXPECT_EQ(var.Get(), u8'C'); var = u'D'; EXPECT_EQ(var.Get(), u'D'); var = U'E'; EXPECT_EQ(var.Get(), U'E'); var = true; EXPECT_EQ(var.Get(), true); var = static_cast("string"); EXPECT_EQ(var.Get(), "string"); var = static_cast(u8"string"); EXPECT_EQ(var.Get(), u8"string"); var = static_cast(u"string"); EXPECT_EQ(var.Get(), u"string"); var = static_cast(U"string"); EXPECT_EQ(var.Get(), U"string"); var = static_cast(L"string"); EXPECT_EQ(var.Get(), L"string"); } TEST_F(CConstVariantTest, LiteralIndirectValueAssignment) { CConstVariant var; bool b = true; var = b; EXPECT_EQ(var.Get(), true); int8_t i8 = 10; var = i8; EXPECT_EQ(var.Get(), 10); int16_t i16 = 20; var = i16; EXPECT_EQ(var.Get(), 20); int32_t i32 = 30; var = i32; EXPECT_EQ(var.Get(), 30); int64_t i64 = 40; var = i64; EXPECT_EQ(var.Get(), 40); uint8_t ui8 = 50; var = ui8; EXPECT_EQ(var.Get(), 50); uint16_t ui16 = 60; var = ui16; EXPECT_EQ(var.Get(), 60); uint32_t ui32 = 70; var = ui32; EXPECT_EQ(var.Get(), 70u); uint64_t ui64 = 80; var = ui64; EXPECT_EQ(var.Get(), 80ull); float f = 90.0; var = f; EXPECT_EQ(var.Get(), 90.0); double d = 100.0; var = d; EXPECT_EQ(var.Get(), 100.0); long double ld = 110.0; var = ld; EXPECT_EQ(var.Get(), 110.0); std::string ss = "string"; var = ss; EXPECT_EQ(var.Get(), "string"); std::string ssUtf8 = u8"string"; var = ssUtf8; EXPECT_EQ(var.Get(), u8"string"); std::u16string ssUtf16 = u"string"; var = ssUtf16; EXPECT_EQ(var.Get(), u"string"); std::u32string ssUtf32 = U"string"; var = ssUtf32; EXPECT_EQ(var.Get(), U"string"); std::wstring ssWide = L"string"; var = ssWide; EXPECT_EQ(var.Get(), L"string"); } TEST_F(CConstVariantTest, TypePromotion) { CConstVariant var; bool b = true; var = b; EXPECT_EQ(var.Get(), 1); EXPECT_EQ(var.Get(), 1); EXPECT_EQ(var.Get(), 1); EXPECT_EQ(var.Get(), 1u); EXPECT_EQ(var.Get(), 1); EXPECT_EQ(var.Get(), 1u); EXPECT_EQ(var.Get(), 1); EXPECT_EQ(var.Get(), 1ull); EXPECT_EQ(var.Get(), 1.0f); EXPECT_EQ(var.Get(), 1.0); EXPECT_EQ(var.Get(), 1.0l); int8_t i8 = -10; var = i8; EXPECT_EQ(var.Get(), 0xf6); EXPECT_EQ(var.Get(), -10); EXPECT_EQ(var.Get(), 0xfff6); EXPECT_EQ(var.Get(), -10); EXPECT_EQ(var.Get(), 0xfffffff6ul); EXPECT_EQ(var.Get(), -10); EXPECT_EQ(var.Get(), 0xfffffffffffffff6ull); EXPECT_EQ(var.Get(), -10.0f); EXPECT_EQ(var.Get(), -10.0); EXPECT_EQ(var.Get(), -10.0l); uint8_t ui8 = 50; var = ui8; EXPECT_EQ(var.Get(), 50); EXPECT_EQ(var.Get(), 50u); EXPECT_EQ(var.Get(), 50); EXPECT_EQ(var.Get(), 50u); EXPECT_EQ(var.Get(), 50); EXPECT_EQ(var.Get(), 50ull); EXPECT_EQ(var.Get(), 50.0f); EXPECT_EQ(var.Get(), 50.0); EXPECT_EQ(var.Get(), 50.0l); int16_t i16 = -20; var = i16; EXPECT_EQ(var.Get(), 0xffec); EXPECT_EQ(var.Get(), -20); EXPECT_EQ(var.Get(), 0xffffffecul); EXPECT_EQ(var.Get(), -20); EXPECT_EQ(var.Get(), 0xffffffffffffffecull); EXPECT_EQ(var.Get(), -20.0f); EXPECT_EQ(var.Get(), -20.0); EXPECT_EQ(var.Get(), -20.0l); uint16_t ui16 = 60; var = ui16; EXPECT_EQ(var.Get(), 60); EXPECT_EQ(var.Get(), 60u); EXPECT_EQ(var.Get(), 60); EXPECT_EQ(var.Get(), 60ull); EXPECT_EQ(var.Get(), 60.0f); EXPECT_EQ(var.Get(), 60.0); EXPECT_EQ(var.Get(), 60.0l); int32_t i32 = -30; var = i32; EXPECT_EQ(var.Get(), 0xffffffe2ul); EXPECT_EQ(var.Get(), -30); EXPECT_EQ(var.Get(), 0xffffffffffffffe2ull); EXPECT_EQ(var.Get(), -30.0f); EXPECT_EQ(var.Get(), -30.0); EXPECT_EQ(var.Get(), -30.0l); uint32_t ui32 = 70; var = ui32; EXPECT_EQ(var.Get(), 70); EXPECT_EQ(var.Get(), 70ull); EXPECT_EQ(var.Get(), 70.0f); EXPECT_EQ(var.Get(), 70.0); EXPECT_EQ(var.Get(), 70.0l); int64_t i64 = -40; var = i64; EXPECT_EQ(var.Get(), 0xffffffffffffffd8ull); EXPECT_EQ(var.Get(), -40.0f); EXPECT_EQ(var.Get(), -40.0); EXPECT_EQ(var.Get(), -40.0l); uint64_t ui64 = 80; var = ui64; EXPECT_EQ(var.Get(), 80.0f); EXPECT_EQ(var.Get(), 80.0); EXPECT_EQ(var.Get(), 80.0l); float f = -90.0; var = f; EXPECT_EQ(var.Get(), -90.0); EXPECT_EQ(var.Get(), -90.0l); double d = -100.0; var = d; EXPECT_EQ(var.Get(), -100.0l); } TEST_F(CConstVariantTest, TypeDemotion) { CConstVariant var; int8_t i8 = 1; var = i8; EXPECT_EQ(var.Get(), true); var = std::numeric_limits::min(); EXPECT_EQ(var.Get(), true); var = std::numeric_limits::max(); EXPECT_EQ(var.Get(), true); uint8_t ui8 = 50; var = ui8; EXPECT_EQ(var.Get(), 50); EXPECT_EQ(var.Get(), true); var = std::numeric_limits::max(); EXPECT_THROW(var.Get(), CCompileException); int16_t i16 = -20; var = i16; EXPECT_EQ(var.Get(), 0xec); EXPECT_EQ(var.Get(), -20); var = std::numeric_limits::min(); EXPECT_THROW(var.Get(), CCompileException); var = std::numeric_limits::max(); EXPECT_THROW(var.Get(), CCompileException); uint16_t ui16 = 60; var = ui16; EXPECT_EQ(var.Get(), 60); EXPECT_EQ(var.Get(), 60); var = std::numeric_limits::max(); EXPECT_THROW(var.Get(), CCompileException); int32_t i32 = -30; var = i32; EXPECT_EQ(var.Get(), 0xffe2); EXPECT_EQ(var.Get(), -30); var = std::numeric_limits::min(); EXPECT_THROW(var.Get(), CCompileException); var = std::numeric_limits::max(); EXPECT_THROW(var.Get(), CCompileException); uint32_t ui32 = 70; var = ui32; EXPECT_EQ(var.Get(), 70); EXPECT_EQ(var.Get(), 70); var = std::numeric_limits::max(); EXPECT_THROW(var.Get(), CCompileException); int64_t i64 = -40; var = i64; EXPECT_EQ(var.Get(), 0xffffffd8); EXPECT_EQ(var.Get(), -40); var = std::numeric_limits::min(); EXPECT_THROW(var.Get(), CCompileException); var = std::numeric_limits::max(); EXPECT_THROW(var.Get(), CCompileException); uint64_t ui64 = 80; var = ui64; EXPECT_EQ(var.Get(), 80); EXPECT_EQ(var.Get(), 80); var = std::numeric_limits::max(); EXPECT_THROW(var.Get(), CCompileException); float f = 90.0; var = f; EXPECT_THROW(var.Get(), CCompileException); EXPECT_THROW(var.Get(), CCompileException); double d = 100.0; var = d; EXPECT_EQ(var.Get(), 100.0f); var = std::numeric_limits::max(); EXPECT_THROW(var.Get(), CCompileException); var = std::numeric_limits::min(); EXPECT_THROW(var.Get(), CCompileException); var = std::numeric_limits::lowest(); EXPECT_THROW(var.Get(), CCompileException); if (std::numeric_limits::max() < std::numeric_limits::max()) { long double ld = 110.0; var = ld; EXPECT_EQ(var.Get(), 110.0); var = std::numeric_limits::max(); EXPECT_THROW(var.Get(), CCompileException); var = std::numeric_limits::min(); EXPECT_THROW(var.Get(), CCompileException); var = std::numeric_limits::lowest(); EXPECT_THROW(var.Get(), CCompileException); } } TEST_F(CConstVariantTest, InvalidConversion) { EXPECT_THROW(CConstVariant(90).Get(), CCompileException); EXPECT_THROW(CConstVariant(90.0f).Get(), CCompileException); EXPECT_THROW(CConstVariant(100.0).Get(), CCompileException); EXPECT_THROW(CConstVariant(110.0l).Get(), CCompileException); EXPECT_THROW(CConstVariant("string").Get(), CCompileException); EXPECT_THROW(CConstVariant(u8"string").Get(), CCompileException); EXPECT_THROW(CConstVariant(u"string").Get(), CCompileException); EXPECT_THROW(CConstVariant(U"string").Get(), CCompileException); EXPECT_THROW(CConstVariant(L"string").Get(), CCompileException); } TEST_F(CConstVariantTest, ArithmicOperatorLogicalNot) { CConstVariant var1(true); CConstVariant var2 = !var1; EXPECT_EQ(var2.Get(), 0u); var1 = 100.0; EXPECT_THROW(var2 = !var1, CCompileException); var1 = 100; var2 = !var1; EXPECT_EQ(var2.Get(), 0); } TEST_F(CConstVariantTest, ArithmicOperatorBitwiseNot) { CConstVariant var1(static_cast(0b1011100010ull)); CConstVariant var2 = ~var1; EXPECT_EQ(var2.Get(), 0b1111110100011101ull); var1 = 100.0; EXPECT_THROW(var2 = ~var1, CCompileException); var1 = false; EXPECT_THROW(var2 = ~var1, CCompileException); var1 = static_cast(0x0f); var2 = ~var1; EXPECT_EQ(var2.Get(), 0xfff0); } TEST_F(CConstVariantTest, ArithmicOperatorConfirmation) { CConstVariant var1(true); CConstVariant var2 = +var1; EXPECT_EQ(var2.Get(), 1u); var1 = 100.0; var2 = +var1; EXPECT_EQ(var2.Get(), 100.0f); var1 = 100; var2 = +var1; EXPECT_EQ(var2.Get(), 100); } TEST_F(CConstVariantTest, ArithmicOperatorNegetion) { CConstVariant var1(static_cast('A')); CConstVariant var2 = -var1; EXPECT_EQ(var2.Get(), -65); var1 = true; EXPECT_THROW(var2 = -var1, CCompileException); var1 = 100.0; var2 = -var1; EXPECT_EQ(var2.Get(), -100.0f); var1 = 100; var2 = -var1; EXPECT_EQ(var2.Get(), -100); } TEST_F(CConstVariantTest, ArithmicOperatorMultiplication) { CConstVariant var1(90); CConstVariant var2(45); CConstVariant var3 = var1 * var2; EXPECT_EQ(var3.Get(), 4050u); var1 = 100.0; var2 = 45.0; var3 = var1 * var2; EXPECT_EQ(var3.Get(), 4500); var1 = 100.0; var2 = 'A'; var3 = var1 * var2; EXPECT_EQ(var3.Get(), 6500); } TEST_F(CConstVariantTest, ArithmicOperatorDivision) { CConstVariant var1(90); CConstVariant var2(45); CConstVariant var3 = var1 / var2; EXPECT_EQ(var3.Get(), 2); var1 = 100.0; var2 = 45.0; var3 = var1 / var2; EXPECT_EQ(var3.Get(), 100.0/45.0); var1 = 130; var2 = 'A'; var3 = var1 / var2; EXPECT_EQ(var3.Get(), 2u); EXPECT_THROW(var3 / 0, CCompileException); } TEST_F(CConstVariantTest, ArithmicOperatorAddition) { CConstVariant var1(90); CConstVariant var2(45); CConstVariant var3 = var1 + var2; EXPECT_EQ(var3.Get(), 135u); var1 = 100.0; var2 = 45.0; var3 = var1 + var2; EXPECT_EQ(var3.Get(), 145); var1 = 100.0; var2 = 'A'; var3 = var1 + var2; EXPECT_EQ(var3.Get(), 165); } TEST_F(CConstVariantTest, ArithmicOperatorSubtraction) { CConstVariant var1(90); CConstVariant var2(45); CConstVariant var3 = var1 - var2; EXPECT_EQ(var3.Get(), 45u); var1 = 100.0; var2 = 45.0; var3 = var1 - var2; EXPECT_EQ(var3.Get(), 55); var1 = 0.0; var2 = 'A'; var3 = var1 - var2; EXPECT_EQ(var3.Get(), -65); } TEST_F(CConstVariantTest, ArithmicOperatorRemainder) { CConstVariant var1(90); CConstVariant var2(40); CConstVariant var3 = var1 % var2; EXPECT_EQ(var3.Get(), 10); var1 = 100.0; var2 = 45.0; EXPECT_THROW(var1 % var2, CCompileException); var1 = 130; var2 = 'A'; var3 = var1 % var2; EXPECT_EQ(var3.Get(), 0u); EXPECT_THROW(var3 % 0, CCompileException); } TEST_F(CConstVariantTest, ArithmicOperatorShiftLeft) { CConstVariant var1(90); CConstVariant var2(3); CConstVariant var3 = var1 << var2; EXPECT_EQ(var3.Get(), 720u); var1 = 100.0; var2 = 2.0; EXPECT_THROW(var1 << var2, CCompileException); var1 = static_cast('A'); var2 = static_cast(2); var3 = var1 << var2; EXPECT_EQ(var3.Get(), 260u); } TEST_F(CConstVariantTest, ArithmicOperatorShiftRight) { CConstVariant var1(90); CConstVariant var2(3); CConstVariant var3 = var1 >> var2; EXPECT_EQ(var3.Get(), 11u); var1 = 100.0; var2 = 2.0; EXPECT_THROW(var1 >> var2, CCompileException); var1 = 'A'; var2 = static_cast(2); var3 = var1 >> var2; EXPECT_EQ(var3.Get(), 16u); } TEST_F(CConstVariantTest, ArithmicOperatorBitwiseAnd) { CConstVariant var1(0b10101010); CConstVariant var2(0b11110000); CConstVariant var3 = var1 & var2; EXPECT_EQ(var3.Get(), 0b10100000u); var1 = 100.0; var2 = 2.0; EXPECT_THROW(var1 & var2, CCompileException); var1 = 'A'; var2 = static_cast(1); var3 = var1 & var2; EXPECT_EQ(var3.Get(), 1u); } TEST_F(CConstVariantTest, ArithmicOperatorBitwiseXor) { CConstVariant var1(0b10101010); CConstVariant var2(0b11110000); CConstVariant var3 = var1 ^ var2; EXPECT_EQ(var3.Get(), 0b1011010u); var1 = 100.0; var2 = 2.0; EXPECT_THROW(var1 ^ var2, CCompileException); var1 = 'A'; var2 = static_cast(1); var3 = var1 ^ var2; EXPECT_EQ(var3.Get(), 64u); } TEST_F(CConstVariantTest, ArithmicOperatorBitwiseOr) { CConstVariant var1(0b10101010); CConstVariant var2(0b11110000); CConstVariant var3 = var1 | var2; EXPECT_EQ(var3.Get(), 0b11111010u); var1 = 100.0; var2 = 2.0; EXPECT_THROW(var1 | var2, CCompileException); var1 = 'A'; var2 = static_cast(2); var3 = var1 | var2; EXPECT_EQ(var3.Get(), 67u); } TEST_F(CConstVariantTest, ArithmicOperatorLogicalAnd) { CConstVariant var1(90); CConstVariant var2(45); CConstVariant var3 = var1 && var2; EXPECT_EQ(var3.Get(), 1u); var1 = 100.0; var2 = 45.0; var3 = 100.0; CConstVariant var4 = 45.0; CConstVariant var5 = var1 == var3 && var2 == var4; EXPECT_EQ(var3.Get(), true); var1 = 65ull; var2 = 'A'; var3 = true; var4 = var1 == var2 && var3; EXPECT_EQ(var4.Get(), true); } TEST_F(CConstVariantTest, ArithmicOperatorLogicalOr) { CConstVariant var1(90); CConstVariant var2(false); CConstVariant var3 = var1 || var2; EXPECT_EQ(var3.Get(), 1u); var1 = 100.0; var2 = 45.0; var3 = 190.0; CConstVariant var4 = 45.0; CConstVariant var5 = var1 == var3 || var2 == var4; EXPECT_EQ(var3.Get(), true); var1 = 65ull; var2 = 'A'; var3 = false; var4 = var1 == var2 || var3; EXPECT_EQ(var4.Get(), true); } TEST_F(CConstVariantTest, ArithmicOperatorCompareSmaller) { CConstVariant var1(45); CConstVariant var2(90); CConstVariant var3 = var1 < var2; EXPECT_EQ(var3.Get(), 1u); var1 = 100.0; var2 = 45.0; var3 = var2 < var1; EXPECT_EQ(var3.Get(), true); var1 = 65ull; var2 = 'A'; var3 = var1 < var2; EXPECT_EQ(var3.Get(), false); } TEST_F(CConstVariantTest, ArithmicOperatorCompareSmallerOrEqual) { CConstVariant var1(45); CConstVariant var2(90); CConstVariant var3 = var1 <= var2; EXPECT_EQ(var3.Get(), 1u); var1 = 100.0; var2 = 45.0; var3 = var2 <= var1; EXPECT_EQ(var3.Get(), true); var1 = 65ull; var2 = 'A'; var3 = var1 <= var2; EXPECT_EQ(var3.Get(), true); } TEST_F(CConstVariantTest, ArithmicOperatorCompareGreater) { CConstVariant var1(90); CConstVariant var2(45); CConstVariant var3 = var1 > var2; EXPECT_EQ(var3.Get(), 1u); var1 = 45.0; var2 = 100.0; var3 = var2 > var1; EXPECT_EQ(var3.Get(), true); var1 = 65ull; var2 = 'A'; var3 = var1 > var2; EXPECT_EQ(var3.Get(), false); } TEST_F(CConstVariantTest, ArithmicOperatorCompareGreaterOrEqual) { CConstVariant var1(90); CConstVariant var2(45); CConstVariant var3 = var1 >= var2; EXPECT_EQ(var3.Get(), 1u); var1 = 45.0; var2 = 100.0; var3 = var2 >= var1; EXPECT_EQ(var3.Get(), true); var1 = 65ull; var2 = 'A'; var3 = var1 >= var2; EXPECT_EQ(var3.Get(), true); } TEST_F(CConstVariantTest, ArithmicOperatorCompareEqual) { CConstVariant var1(90); CConstVariant var2(45); CConstVariant var3 = var1 == var2; EXPECT_EQ(var3.Get(), 0u); var1 = 45.0; var2 = 100.0; var3 = var2 == var1; EXPECT_EQ(var3.Get(), false); var1 = 65ull; var2 = 'A'; var3 = var1 == var2; EXPECT_EQ(var3.Get(), true); } TEST_F(CConstVariantTest, ArithmicOperatorCompareNotEqual) { CConstVariant var1(90); CConstVariant var2(45); CConstVariant var3 = var1 != var2; EXPECT_EQ(var3.Get(), 1u); var1 = 45.0; var2 = 100.0; var3 = var2 != var1; EXPECT_EQ(var3.Get(), true); var1 = 65ull; var2 = 'A'; var3 = var1 != var2; EXPECT_EQ(var3.Get(), false); }