// Copyright 2014 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include "src/base/bounds.h" #include "src/utils/utils.h" #include "testing/gtest-support.h" namespace v8 { namespace internal { template class UtilsTest : public ::testing::Test {}; using IntegerTypes = ::testing::Types; TYPED_TEST_SUITE(UtilsTest, IntegerTypes); TYPED_TEST(UtilsTest, SaturateSub) { TypeParam min = std::numeric_limits::min(); TypeParam max = std::numeric_limits::max(); EXPECT_EQ(SaturateSub(min, 0), min); EXPECT_EQ(SaturateSub(max, 0), max); EXPECT_EQ(SaturateSub(max, min), max); EXPECT_EQ(SaturateSub(min, max), min); EXPECT_EQ(SaturateSub(min, max / 3), min); EXPECT_EQ(SaturateSub(min + 1, 2), min); if (std::numeric_limits::is_signed) { EXPECT_EQ(SaturateSub(min, min), static_cast(0)); EXPECT_EQ(SaturateSub(0, min), max); EXPECT_EQ(SaturateSub(max / 3, min), max); EXPECT_EQ(SaturateSub(max / 5, min), max); EXPECT_EQ(SaturateSub(min / 3, max), min); EXPECT_EQ(SaturateSub(min / 9, max), min); EXPECT_EQ(SaturateSub(max, min / 3), max); EXPECT_EQ(SaturateSub(min, max / 3), min); EXPECT_EQ(SaturateSub(max / 3 * 2, min / 2), max); EXPECT_EQ(SaturateSub(min / 3 * 2, max / 2), min); } else { EXPECT_EQ(SaturateSub(min, min), min); EXPECT_EQ(SaturateSub(0, min), min); EXPECT_EQ(SaturateSub(0, max), min); EXPECT_EQ(SaturateSub(max / 3, max), min); EXPECT_EQ(SaturateSub(max - 3, max), min); } TypeParam test_cases[] = {static_cast(min / 23), static_cast(max / 3), 63, static_cast(min / 6), static_cast(max / 55), static_cast(min / 2), static_cast(max / 2), 0, 1, 2, 3, 4, 42}; TRACED_FOREACH(TypeParam, x, test_cases) { TRACED_FOREACH(TypeParam, y, test_cases) { if (std::numeric_limits::is_signed) { EXPECT_EQ(SaturateSub(x, y), x - y); } else { EXPECT_EQ(SaturateSub(x, y), y > x ? min : x - y); } } } } TYPED_TEST(UtilsTest, SaturateAdd) { TypeParam min = std::numeric_limits::min(); TypeParam max = std::numeric_limits::max(); EXPECT_EQ(SaturateAdd(min, min), min); EXPECT_EQ(SaturateAdd(max, max), max); EXPECT_EQ(SaturateAdd(min, min / 3), min); EXPECT_EQ(SaturateAdd(max / 8 * 7, max / 3 * 2), max); EXPECT_EQ(SaturateAdd(min / 3 * 2, min / 8 * 7), min); EXPECT_EQ(SaturateAdd(max / 20 * 18, max / 25 * 18), max); EXPECT_EQ(SaturateAdd(min / 3 * 2, min / 3 * 2), min); EXPECT_EQ(SaturateAdd(max - 1, 2), max); EXPECT_EQ(SaturateAdd(max - 100, 101), max); TypeParam test_cases[] = {static_cast(min / 23), static_cast(max / 3), 63, static_cast(min / 6), static_cast(max / 55), static_cast(min / 2), static_cast(max / 2), 0, 1, 2, 3, 4, 42}; TRACED_FOREACH(TypeParam, x, test_cases) { TRACED_FOREACH(TypeParam, y, test_cases) { EXPECT_EQ(SaturateAdd(x, y), x + y); } } } TYPED_TEST(UtilsTest, PassesFilterTest) { EXPECT_TRUE( PassesFilter(base::CStrVector("abcdefg"), base::CStrVector("abcdefg"))); EXPECT_TRUE( PassesFilter(base::CStrVector("abcdefg"), base::CStrVector("abcdefg*"))); EXPECT_TRUE( PassesFilter(base::CStrVector("abcdefg"), base::CStrVector("abc*"))); EXPECT_TRUE(PassesFilter(base::CStrVector("abcdefg"), base::CStrVector("*"))); EXPECT_TRUE( PassesFilter(base::CStrVector("abcdefg"), base::CStrVector("-~"))); EXPECT_TRUE( PassesFilter(base::CStrVector("abcdefg"), base::CStrVector("-abcdefgh"))); EXPECT_TRUE(PassesFilter(base::CStrVector("abdefg"), base::CStrVector("-"))); EXPECT_FALSE( PassesFilter(base::CStrVector("abcdefg"), base::CStrVector("-abcdefg"))); EXPECT_FALSE( PassesFilter(base::CStrVector("abcdefg"), base::CStrVector("-abcdefg*"))); EXPECT_FALSE( PassesFilter(base::CStrVector("abcdefg"), base::CStrVector("-abc*"))); EXPECT_FALSE( PassesFilter(base::CStrVector("abcdefg"), base::CStrVector("-*"))); EXPECT_FALSE( PassesFilter(base::CStrVector("abcdefg"), base::CStrVector("~"))); EXPECT_FALSE(PassesFilter(base::CStrVector("abcdefg"), base::CStrVector(""))); EXPECT_FALSE( PassesFilter(base::CStrVector("abcdefg"), base::CStrVector("abcdefgh"))); EXPECT_TRUE(PassesFilter(base::CStrVector(""), base::CStrVector(""))); EXPECT_TRUE(PassesFilter(base::CStrVector(""), base::CStrVector("*"))); EXPECT_FALSE(PassesFilter(base::CStrVector(""), base::CStrVector("-"))); EXPECT_FALSE(PassesFilter(base::CStrVector(""), base::CStrVector("-*"))); EXPECT_FALSE(PassesFilter(base::CStrVector(""), base::CStrVector("a"))); } TEST(UtilsTest, IsInBounds) { // for column consistency and terseness #define INB(x, y, z) EXPECT_TRUE(base::IsInBounds(x, y, z)) #define OOB(x, y, z) EXPECT_FALSE(base::IsInBounds(x, y, z)) INB(0, 0, 1); INB(0, 1, 1); INB(1, 0, 1); OOB(0, 2, 1); OOB(2, 0, 1); INB(0, 0, 2); INB(0, 1, 2); INB(0, 2, 2); INB(0, 0, 2); INB(1, 0, 2); INB(2, 0, 2); OOB(0, 3, 2); OOB(3, 0, 2); INB(0, 1, 2); INB(1, 1, 2); OOB(1, 2, 2); OOB(2, 1, 2); const size_t max = std::numeric_limits::max(); const size_t half = max / 2; // limit cases. INB(0, 0, max); INB(0, 1, max); INB(1, 0, max); INB(max, 0, max); INB(0, max, max); INB(max - 1, 0, max); INB(0, max - 1, max); INB(max - 1, 1, max); INB(1, max - 1, max); INB(half, half, max); INB(half + 1, half, max); INB(half, half + 1, max); OOB(max, 0, 0); OOB(0, max, 0); OOB(max, 0, 1); OOB(0, max, 1); OOB(max, 0, 2); OOB(0, max, 2); OOB(max, 0, max - 1); OOB(0, max, max - 1); // wraparound cases. OOB(max, 1, max); OOB(1, max, max); OOB(max - 1, 2, max); OOB(2, max - 1, max); OOB(half + 1, half + 1, max); OOB(half + 1, half + 1, max); #undef INB #undef OOB } } // namespace internal } // namespace v8