Something went wrong. Try again.
OpenMW is an open implementation of the Morrowind engine
Something went wrong. Try again.
17 kB · 470 lines
C++
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471#include <components/vfs/pathutil.hpp>
#include <gtest/gtest.h>
#include <sstream>
namespace VFS::Path{ namespace { using namespace testing;
template <class T0, class T1> struct TypePair { using Type0 = T0; using Type1 = T1; };
struct VFSPathIsNormalizedTest : TestWithParam<std::pair<std::string_view, bool>> { };
TEST_P(VFSPathIsNormalizedTest, shouldReturnExpectedResult) { EXPECT_EQ(isNormalized(GetParam().first), GetParam().second); }
const std::pair<std::string_view, bool> isNormalizedTestParams[] = { { std::string_view(), true }, { "foo", true }, { "foo/bar", true }, { "foo/bar/baz", true }, { "/foo", false }, { "foo//", false }, { "foo\\", false }, { "Foo", false }, };
INSTANTIATE_TEST_SUITE_P(IsNormalizedTestParams, VFSPathIsNormalizedTest, ValuesIn(isNormalizedTestParams));
TEST(VFSPathNormalizeFilenameInPlaceTest, shouldRemoveLeadingSeparators) { std::string value("//foo"); normalizeFilenameInPlace(value); EXPECT_EQ(value, "foo"); }
TEST(VFSPathNormalizeFilenameInPlaceTest, shouldRemoveDuplicatedSeparators) { std::string value("foo//bar///baz"); normalizeFilenameInPlace(value); EXPECT_EQ(value, "foo/bar/baz"); }
TEST(VFSPathNormalizeFilenameInPlaceTest, shouldRemoveDuplicatedLeadingSeparator) { std::string value("//foo"); normalizeFilenameInPlace(value); EXPECT_EQ(value, "foo"); }
TEST(VFSPathExtensionViewTest, shouldSupportDefaultConstructor) { constexpr ExtensionView extension; EXPECT_TRUE(extension.empty()); EXPECT_EQ(extension.value(), ""); }
TEST(VFSPathExtensionViewTest, shouldSupportConstexprConstructorFromConstCharPtr) { constexpr ExtensionView extension("png"); EXPECT_FALSE(extension.empty()); EXPECT_EQ(extension.value(), "png"); }
TEST(VFSPathExtensionViewTest, constructorShouldThrowExceptionOnNotNormalizedValue) { EXPECT_THROW([] { ExtensionView("PNG"); }(), std::invalid_argument); }
TEST(VFSPathExtensionViewTest, constructorShouldThrowExceptionIfValueContainsExtensionSeparator) { EXPECT_THROW([] { ExtensionView(".png"); }(), std::invalid_argument); }
TEST(VFSPathExtensionViewTest, constructorShouldThrowExceptionIfValueContainsSeparator) { EXPECT_THROW([] { ExtensionView("/png"); }(), std::invalid_argument); }
template <class T> struct VFSPathExtensionViewOperatorsTest : Test { };
TYPED_TEST_SUITE_P(VFSPathExtensionViewOperatorsTest);
TYPED_TEST_P(VFSPathExtensionViewOperatorsTest, supportsEqual) { using Type0 = typename TypeParam::Type0; using Type1 = typename TypeParam::Type1; const Type0 extension{ "png" }; const Type1 otherEqual{ "png" }; const Type1 otherNotEqual{ "jpg" }; EXPECT_EQ(extension, otherEqual); EXPECT_EQ(otherEqual, extension); EXPECT_NE(extension, otherNotEqual); EXPECT_NE(otherNotEqual, extension); }
TYPED_TEST_P(VFSPathExtensionViewOperatorsTest, supportsLess) { using Type0 = typename TypeParam::Type0; using Type1 = typename TypeParam::Type1; const Type0 extension{ "png" }; const Type1 otherEqual{ "png" }; const Type1 otherLess{ "jpg" }; const Type1 otherGreater{ "tga" }; EXPECT_FALSE(extension < otherEqual); EXPECT_FALSE(otherEqual < extension); EXPECT_LT(otherLess, extension); EXPECT_FALSE(extension < otherLess); EXPECT_LT(extension, otherGreater); EXPECT_FALSE(otherGreater < extension); }
REGISTER_TYPED_TEST_SUITE_P(VFSPathExtensionViewOperatorsTest, supportsEqual, supportsLess);
using VFSPathExtensionViewOperatorsTypePairs = Types<TypePair<ExtensionView, ExtensionView>, TypePair<ExtensionView, const char*>, TypePair<ExtensionView, std::string>, TypePair<ExtensionView, std::string_view>>;
INSTANTIATE_TYPED_TEST_SUITE_P( Typed, VFSPathExtensionViewOperatorsTest, VFSPathExtensionViewOperatorsTypePairs);
TEST(VFSPathNormalizedTest, shouldSupportDefaultConstructor) { const Normalized value; EXPECT_EQ(value.value(), ""); }
TEST(VFSPathNormalizedTest, shouldSupportConstructorFromString) { const std::string string("Foo\\Bar/baz"); const Normalized value(string); EXPECT_EQ(value.value(), "foo/bar/baz"); }
TEST(VFSPathNormalizedTest, shouldSupportConstructorFromConstCharPtr) { const char* const ptr = "Foo\\Bar/baz"; const Normalized value(ptr); EXPECT_EQ(value.value(), "foo/bar/baz"); }
TEST(VFSPathNormalizedTest, shouldSupportConstructorFromStringView) { const std::string_view view = "Foo\\Bar/baz"; const Normalized value(view); EXPECT_EQ(value.view(), "foo/bar/baz"); }
TEST(VFSPathNormalizedTest, shouldSupportConstructorFromNormalizedView) { const NormalizedView view("foo/bar/baz"); const Normalized value(view); EXPECT_EQ(value.view(), "foo/bar/baz"); }
TEST(VFSPathNormalizedTest, supportMovingValueOut) { Normalized value("Foo\\Bar/baz"); EXPECT_EQ(std::move(value).value(), "foo/bar/baz"); EXPECT_EQ(value.value(), ""); }
TEST(VFSPathNormalizedTest, isNotEqualToNotNormalized) { const Normalized value("Foo\\Bar/baz"); EXPECT_NE(value.value(), "Foo\\Bar/baz"); }
TEST(VFSPathNormalizedTest, shouldSupportOperatorLeftShiftToOStream) { const Normalized value("Foo\\Bar/baz"); std::stringstream stream; stream << value; EXPECT_EQ(stream.str(), "foo/bar/baz"); }
TEST(VFSPathNormalizedTest, shouldSupportOperatorDivEqual) { Normalized value("foo/bar"); value /= NormalizedView("baz"); EXPECT_EQ(value.value(), "foo/bar/baz"); }
TEST(VFSPathNormalizedTest, shouldSupportOperatorDivEqualWithStringView) { Normalized value("foo/bar"); value /= std::string_view("BAZ"); EXPECT_EQ(value.value(), "foo/bar/baz"); }
TEST(VFSPathNormalizedTest, operatorDivShouldNormalizeSuffix) { Normalized value("foo/bar"); value /= std::string_view("\\A\\\\B"); EXPECT_EQ(value.value(), "foo/bar/a/b"); }
TEST(VFSPathNormalizedTest, operatorDivForNormalizedViewShouldNotPrependSeparatorToEmpty) { Normalized value; value /= NormalizedView("a"); EXPECT_EQ(value.value(), "a"); }
TEST(VFSPathNormalizedTest, operatorDivForStringViewShouldNotPrependSeparatorToEmpty) { Normalized value; value /= std::string_view("a"); EXPECT_EQ(value.value(), "a"); }
TEST(VFSPathNormalizedTest, changeExtensionShouldReplaceAfterLastDot) { Normalized value("foo/ba.r.a"); constexpr ExtensionView extension("so"); ASSERT_TRUE(value.changeExtension(extension)); EXPECT_EQ(value.value(), "foo/ba.r.so"); }
TEST(VFSPathNormalizedTest, changeExtensionShouldIgnorePathWithoutADot) { Normalized value("foo/bar"); constexpr ExtensionView extension("so"); ASSERT_FALSE(value.changeExtension(extension)); EXPECT_EQ(value.value(), "foo/bar"); }
TEST(VFSPathNormalizedTest, changeExtensionShouldIgnorePathWithDotBeforeSeparator) { Normalized value("foo.bar/baz"); constexpr ExtensionView extension("so"); ASSERT_FALSE(value.changeExtension(extension)); EXPECT_EQ(value.value(), "foo.bar/baz"); }
TEST(VFSPathNormalizedTest, changeExtensionShouldReplaceWithShorterExtension) { Normalized value("foo/bar.nif"); constexpr ExtensionView extension("kf"); ASSERT_TRUE(value.changeExtension(extension)); EXPECT_EQ(value.value(), "foo/bar.kf"); }
TEST(VFSPathNormalizedTest, filenameShouldReturnLastComponentOfThePath) { const Normalized value("foo/bar"); EXPECT_EQ(value.filename(), "bar"); }
TEST(VFSPathNormalizedTest, filenameShouldReturnSameValueForPathWithSingleComponent) { const Normalized value("foo"); EXPECT_EQ(value.filename(), "foo"); }
TEST(VFSPathNormalizedTest, appendShouldAddExtensionWithSeparator) { Normalized value("foo"); value.append(ExtensionView("ext")); EXPECT_EQ(value.value(), "foo.ext"); }
TEST(VFSPathNormalizedTest, appendForEmptyShouldAddExtensionWithSeparator) { Normalized value; value.append(ExtensionView("ext")); EXPECT_EQ(value.value(), ".ext"); }
template <class T> struct VFSPathNormalizedOperatorsTest : Test { };
TYPED_TEST_SUITE_P(VFSPathNormalizedOperatorsTest);
TYPED_TEST_P(VFSPathNormalizedOperatorsTest, supportsEqual) { using Type0 = typename TypeParam::Type0; using Type1 = typename TypeParam::Type1; const Type0 normalized{ "a/foo/bar/baz" }; const Type1 otherEqual{ "a/foo/bar/baz" }; const Type1 otherNotEqual{ "b/foo/bar/baz" }; EXPECT_EQ(normalized, otherEqual); EXPECT_EQ(otherEqual, normalized); EXPECT_NE(normalized, otherNotEqual); EXPECT_NE(otherNotEqual, normalized); }
TYPED_TEST_P(VFSPathNormalizedOperatorsTest, supportsLess) { using Type0 = typename TypeParam::Type0; using Type1 = typename TypeParam::Type1; const Type0 normalized{ "b/foo/bar/baz" }; const Type1 otherEqual{ "b/foo/bar/baz" }; const Type1 otherLess{ "a/foo/bar/baz" }; const Type1 otherGreater{ "c/foo/bar/baz" }; EXPECT_FALSE(normalized < otherEqual); EXPECT_FALSE(otherEqual < normalized); EXPECT_LT(otherLess, normalized); EXPECT_FALSE(normalized < otherLess); EXPECT_LT(normalized, otherGreater); EXPECT_FALSE(otherGreater < normalized); }
REGISTER_TYPED_TEST_SUITE_P(VFSPathNormalizedOperatorsTest, supportsEqual, supportsLess);
using VFSPathNormalizedOperatorsTypePairs = Types<TypePair<Normalized, Normalized>, TypePair<Normalized, const char*>, TypePair<Normalized, std::string>, TypePair<Normalized, std::string_view>, TypePair<Normalized, NormalizedView>, TypePair<NormalizedView, Normalized>, TypePair<NormalizedView, const char*>, TypePair<NormalizedView, std::string>, TypePair<NormalizedView, std::string_view>, TypePair<NormalizedView, NormalizedView>>;
INSTANTIATE_TYPED_TEST_SUITE_P(Typed, VFSPathNormalizedOperatorsTest, VFSPathNormalizedOperatorsTypePairs);
TEST(VFSPathNormalizedViewTest, shouldSupportConstructorFromNormalized) { const Normalized value("Foo\\Bar/baz"); const NormalizedView view(value); EXPECT_EQ(view.value(), "foo/bar/baz"); }
TEST(VFSPathNormalizedViewTest, shouldSupportConstexprConstructorFromNormalizedStringLiteral) { constexpr NormalizedView view("foo/bar/baz"); EXPECT_EQ(view.value(), "foo/bar/baz"); }
TEST(VFSPathNormalizedViewTest, constructorShouldThrowExceptionOnNotNormalized) { EXPECT_THROW([] { NormalizedView("Foo\\Bar/baz"); }(), std::invalid_argument); }
TEST(VFSPathNormalizedViewTest, shouldSupportOperatorDiv) { const NormalizedView a("foo/bar"); const NormalizedView b("baz"); const Normalized result = a / b; EXPECT_EQ(result.value(), "foo/bar/baz"); }
TEST(VFSPathNormalizedViewTest, filenameShouldReturnLastComponentOfThePath) { const NormalizedView value("foo/bar"); EXPECT_EQ(value.filename(), "bar"); }
TEST(VFSPathNormalizedViewTest, filenameShouldReturnSameValueForPathWithSingleComponent) { const NormalizedView value("foo"); EXPECT_EQ(value.filename(), "foo"); }
TEST(VFSPathNormalizedViewTest, stemShouldOmitPathAndExtension) { const NormalizedView value("foo/bar.a"); EXPECT_EQ(value.stem(), "bar"); }
TEST(VFSPathNormalizedViewTest, stemShouldReturnSameValueForPathWithSingleComponent) { const NormalizedView value("foo"); EXPECT_EQ(value.stem(), "foo"); }
TEST(VFSPathNormalizedViewTest, stemShouldIncludeDotsBeforeTheExtension) { const NormalizedView value("last voyage of the u.s.s. constitution.swf"); EXPECT_EQ(value.stem(), "last voyage of the u.s.s. constitution"); }
TEST(VFSPathNormalizedJoinTest, shouldHandleSingleValue) { EXPECT_EQ(join(Normalized("foo")), "foo"); }
TEST(VFSPathNormalizedJoinTest, shouldHandleSingleView) { EXPECT_EQ(join(NormalizedView("foo")), "foo"); }
TEST(VFSPathNormalizedJoinTest, shouldHandleSingleString) { EXPECT_EQ(join(std::string("FOO")), "foo"); }
TEST(VFSPathNormalizedJoinTest, shouldHandleSingleStringView) { EXPECT_EQ(join(std::string_view("FOO")), "foo"); }
TEST(VFSPathNormalizedJoinTest, shouldHandleSingleConstCharArray) { EXPECT_EQ(join("FOO"), "foo"); }
TEST(VFSPathNormalizedJoinTest, shouldHandleSingleConstCharPtr) { const char* const ptr = "FOO"; EXPECT_EQ(join(ptr), "foo"); }
TEST(VFSPathNormalizedJoinTest, shouldHandleSingleExtension) { constexpr ExtensionView extension("foo"); EXPECT_EQ(join(extension), ".foo"); }
TEST(VFSPathNormalizedJoinTest, shouldJoinTwoPathComponents) { EXPECT_EQ(join(NormalizedView("foo"), std::string_view("BAR")), "foo/bar"); }
TEST(VFSPathNormalizedJoinTest, shouldJoinComponentAndExtension) { EXPECT_EQ(join(NormalizedView("foo"), ExtensionView("bar")), "foo.bar"); }
TEST(VFSPathNormalizedJoinTest, shouldJoinTwoExtensions) { EXPECT_EQ(join(ExtensionView("foo"), ExtensionView("bar")), ".foo.bar"); }
TEST(VFSPathNormalizedJoinTest, shouldJoinTreePathComponents) { EXPECT_EQ(join(NormalizedView("a"), std::string_view("B"), Normalized("c")), "a/b/c"); }
TEST(VFSPathNormalizedJoinedCapacityTest, forNormalizedShouldReturnSizeOnly) { EXPECT_EQ(joinedCapacity(Normalized("a")), 1); }
TEST(VFSPathNormalizedJoinedCapacityTest, forConstCharPtrShouldReturnSizeOnly) { EXPECT_EQ(joinedCapacity("a"), 1); }
TEST(VFSPathNormalizedJoinedCapacityTest, forExtensionViewShouldReturnSizePlusSeparator) { EXPECT_EQ(joinedCapacity(ExtensionView("a")), 2); }
TEST(VFSPathNormalizedJoinedCapacityTest, shouldReturnSumOfSizesPlusNumberOfSeparators) { constexpr NormalizedView b("b"); const Normalized c("c"); constexpr std::string_view d("d"); const std::string e("e"); constexpr ExtensionView f("f"); EXPECT_EQ(joinedCapacity("a", b, c, d, e, f), 11); } }}