// // cast_test.cxx // string_utils-test // // Created by Sam Jaffe on 2/14/21. // Copyright © 2021 Sam Jaffe. All rights reserved. // #include "string_utils/cast.h" #include "xcode_gtest_helper.h" using testing::ElementsAre; using testing::FieldsAre; using testing::Pair; using namespace string_utils; TEST(CastIntegerTest, CastsWithBase10) { auto [value, success] = cast("10"); EXPECT_TRUE(success); EXPECT_THAT(value, 10); } TEST(CastIntegerTest, DoesNotCastBase8) { auto [value, success] = cast("010"); EXPECT_TRUE(success); EXPECT_THAT(value, 10); } TEST(CastIntegerTest, DoesNotCastHex) { auto [value, success] = cast("0x10"); EXPECT_FALSE(success); EXPECT_THAT(value, 0); } TEST(CastIntegerTest, FailsOnBadData) { auto [value, success] = cast("x"); EXPECT_FALSE(success); EXPECT_THAT(value, 0); } TEST(CastIntegerTest, FailsOnBadSuffix) { auto [value, success] = cast("10x"); EXPECT_FALSE(success); EXPECT_THAT(value, 10); } TEST(CastIntegerTest, FailsOnOutOfBounds) { auto [_, success] = cast("2147483648"); EXPECT_FALSE(success); } TEST(CastBooleanTest, CastsVariousTrueValues) { EXPECT_THAT(cast("true"), Pair(true, true)); EXPECT_THAT(cast("TRUE"), Pair(true, true)); EXPECT_THAT(cast("YES"), Pair(true, true)); EXPECT_THAT(cast("1"), Pair(true, true)); } TEST(CastBooleanTest, CastsVariousFalseValues) { EXPECT_THAT(cast("false"), Pair(false, true)); EXPECT_THAT(cast("FALSE"), Pair(false, true)); EXPECT_THAT(cast("NO"), Pair(false, true)); EXPECT_THAT(cast("0"), Pair(false, true)); } TEST(CastBooleanTest, DoesNotCastAllIntegers) { auto [_, success] = cast("2"); EXPECT_FALSE(success); } MATCHER_P(HoldsAlternative, typearg, std::string("holds a value of type ") + typeid(typearg).name()) { using T = std::remove_const_t>; return std::holds_alternative(arg); } template auto HoldsAlternative() { return HoldsAlternative(T()); } TEST(CastVariantTest, StringVariantWillAlwaysMatchWhenEncountered) { auto [value, success] = cast>("2"); EXPECT_THAT(value, HoldsAlternative()); } TEST(CastVariantTest, EvaluatesTypesLeftToRight) { auto [value, success] = cast>("2"); EXPECT_THAT(value, HoldsAlternative()); } using pair_t = std::pair; using tuple_t = std::tuple; TEST(CastKeyValTest, FailsOnTooFewTokens) { auto [value, success] = cast(std::vector{"key"}); EXPECT_FALSE(success); } TEST(CastKeyValTest, ParsesTokens) { auto [value, success] = cast(std::vector{"key", "value"}); EXPECT_TRUE(success); EXPECT_THAT(value, Pair("key", "value")); } TEST(CastKeyValTest, FailsOnTooManyTokens) { auto [value, success] = cast(std::vector{"key", "value", "mapping"}); EXPECT_FALSE(success); } TEST(CastTupleTest, FailsOnTooFewTokens) { auto [value, success] = cast(std::vector{"0", "A"}); EXPECT_FALSE(success); } TEST(CastTupleTest, FailsOnTooManyTokens) { auto [value, success] = cast(std::vector{"0", "1", "A", "B"}); EXPECT_FALSE(success); } TEST(CastTupleTest, ParsesIfAllGood) { auto [value, success] = cast(std::vector{"0", "1", "A"}); EXPECT_TRUE(success); EXPECT_THAT(value, FieldsAre(0, 1, "A")); } TEST(CastTupleTest, FailsOnAnyParseError) { auto [value, success] = cast(std::vector{"0", "Q", "A"}); EXPECT_FALSE(success); } struct Bindable { int a; std::string b; }; bool cast(Bindable & out, std::vector const & strs) { return strs.size() == 2 && cast(out.a, strs[0]) && cast(out.b, strs[1]); } struct Positive { int value; }; bool cast(Positive & out, std::string_view str) { return cast(out.value, str) && out.value > 0; } TEST(CastTest, UsesADL) { auto [value, success] = cast(std::vector{"0", "Q"}); EXPECT_TRUE(success); } TEST(CastTest, CanImposeConstraint) { auto [value, success] = cast("0"); EXPECT_FALSE(success); } TEST(CastContainerTest, CanCastVector) { auto [value, success] = cast>(std::vector{"0", "Q", "A"}); EXPECT_TRUE(success); EXPECT_THAT(value, ElementsAre("0", "Q", "A")); } TEST(CastContainerTest, FailsIfBadValueCast) { auto [value, success] = cast>(std::vector{"0", "Q", "A"}); EXPECT_FALSE(success); } TEST(CastContainerTest, CanCastSet) { auto [value, success] = cast>(std::vector{"0", "0", "A"}); EXPECT_TRUE(success); EXPECT_THAT(value, ElementsAre("0", "A")); } TEST(CastContainerTest, CanCastMap) { auto [value, success] = cast>( std::vector{"0=1", "0=2", "A=B"}); EXPECT_TRUE(success); EXPECT_THAT(value, ElementsAre(Pair("0", "1"), Pair("A", "B"))); } TEST(CastContainerTest, FailsIfBadCastOnKey) { auto [value, success] = cast>(std::vector{"0=1", "0=2", "A=B"}); EXPECT_FALSE(success); } TEST(CastContainerTest, FailsIfBadCastOnValue) { auto [value, success] = cast>(std::vector{"0=1", "0=2", "A=B"}); EXPECT_FALSE(success); }