v8/test/unittests/utils/utils-unittest.cc
Dan Elphick 84f3877c15 [cleanup] Split out bit-field.h and bounds.h from utils/utils.h
utils.h itself is fairly large and contains lots of unrelated functions
as well as having a fair number of dependencies itself, so this splits
bounds checking and bit field operations into their own headers in base
and replaces uses of utils.h with the more appropriate header where
possible. (Also fixes some cases where other headers were previously
brought in transitively).

Bug: v8:9810, v8:8912
Change-Id: I76c53f953848a57e2c5bfad6ce45abcd6d2a4f1b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1916604
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Commit-Queue: Dan Elphick <delphick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64983}
2019-11-15 13:00:08 +00:00

206 lines
7.3 KiB
C++

// 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 <limits>
#include "src/base/bounds.h"
#include "src/utils/utils.h"
#include "testing/gtest-support.h"
namespace v8 {
namespace internal {
template <typename T>
class UtilsTest : public ::testing::Test {};
using IntegerTypes =
::testing::Types<signed char, unsigned char,
short, // NOLINT(runtime/int)
unsigned short, // NOLINT(runtime/int)
int, unsigned int, long, // NOLINT(runtime/int)
unsigned long, // NOLINT(runtime/int)
long long, // NOLINT(runtime/int)
unsigned long long, // NOLINT(runtime/int)
int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
int64_t, uint64_t>;
TYPED_TEST_SUITE(UtilsTest, IntegerTypes);
TYPED_TEST(UtilsTest, SaturateSub) {
TypeParam min = std::numeric_limits<TypeParam>::min();
TypeParam max = std::numeric_limits<TypeParam>::max();
EXPECT_EQ(SaturateSub<TypeParam>(min, 0), min);
EXPECT_EQ(SaturateSub<TypeParam>(max, 0), max);
EXPECT_EQ(SaturateSub<TypeParam>(max, min), max);
EXPECT_EQ(SaturateSub<TypeParam>(min, max), min);
EXPECT_EQ(SaturateSub<TypeParam>(min, max / 3), min);
EXPECT_EQ(SaturateSub<TypeParam>(min + 1, 2), min);
if (std::numeric_limits<TypeParam>::is_signed) {
EXPECT_EQ(SaturateSub<TypeParam>(min, min), static_cast<TypeParam>(0));
EXPECT_EQ(SaturateSub<TypeParam>(0, min), max);
EXPECT_EQ(SaturateSub<TypeParam>(max / 3, min), max);
EXPECT_EQ(SaturateSub<TypeParam>(max / 5, min), max);
EXPECT_EQ(SaturateSub<TypeParam>(min / 3, max), min);
EXPECT_EQ(SaturateSub<TypeParam>(min / 9, max), min);
EXPECT_EQ(SaturateSub<TypeParam>(max, min / 3), max);
EXPECT_EQ(SaturateSub<TypeParam>(min, max / 3), min);
EXPECT_EQ(SaturateSub<TypeParam>(max / 3 * 2, min / 2), max);
EXPECT_EQ(SaturateSub<TypeParam>(min / 3 * 2, max / 2), min);
} else {
EXPECT_EQ(SaturateSub<TypeParam>(min, min), min);
EXPECT_EQ(SaturateSub<TypeParam>(0, min), min);
EXPECT_EQ(SaturateSub<TypeParam>(0, max), min);
EXPECT_EQ(SaturateSub<TypeParam>(max / 3, max), min);
EXPECT_EQ(SaturateSub<TypeParam>(max - 3, max), min);
}
TypeParam test_cases[] = {static_cast<TypeParam>(min / 23),
static_cast<TypeParam>(max / 3),
63,
static_cast<TypeParam>(min / 6),
static_cast<TypeParam>(max / 55),
static_cast<TypeParam>(min / 2),
static_cast<TypeParam>(max / 2),
0,
1,
2,
3,
4,
42};
TRACED_FOREACH(TypeParam, x, test_cases) {
TRACED_FOREACH(TypeParam, y, test_cases) {
if (std::numeric_limits<TypeParam>::is_signed) {
EXPECT_EQ(SaturateSub<TypeParam>(x, y), x - y);
} else {
EXPECT_EQ(SaturateSub<TypeParam>(x, y), y > x ? min : x - y);
}
}
}
}
TYPED_TEST(UtilsTest, SaturateAdd) {
TypeParam min = std::numeric_limits<TypeParam>::min();
TypeParam max = std::numeric_limits<TypeParam>::max();
EXPECT_EQ(SaturateAdd<TypeParam>(min, min), min);
EXPECT_EQ(SaturateAdd<TypeParam>(max, max), max);
EXPECT_EQ(SaturateAdd<TypeParam>(min, min / 3), min);
EXPECT_EQ(SaturateAdd<TypeParam>(max / 8 * 7, max / 3 * 2), max);
EXPECT_EQ(SaturateAdd<TypeParam>(min / 3 * 2, min / 8 * 7), min);
EXPECT_EQ(SaturateAdd<TypeParam>(max / 20 * 18, max / 25 * 18), max);
EXPECT_EQ(SaturateAdd<TypeParam>(min / 3 * 2, min / 3 * 2), min);
EXPECT_EQ(SaturateAdd<TypeParam>(max - 1, 2), max);
EXPECT_EQ(SaturateAdd<TypeParam>(max - 100, 101), max);
TypeParam test_cases[] = {static_cast<TypeParam>(min / 23),
static_cast<TypeParam>(max / 3),
63,
static_cast<TypeParam>(min / 6),
static_cast<TypeParam>(max / 55),
static_cast<TypeParam>(min / 2),
static_cast<TypeParam>(max / 2),
0,
1,
2,
3,
4,
42};
TRACED_FOREACH(TypeParam, x, test_cases) {
TRACED_FOREACH(TypeParam, y, test_cases) {
EXPECT_EQ(SaturateAdd<TypeParam>(x, y), x + y);
}
}
}
TYPED_TEST(UtilsTest, PassesFilterTest) {
EXPECT_TRUE(PassesFilter(CStrVector("abcdefg"), CStrVector("abcdefg")));
EXPECT_TRUE(PassesFilter(CStrVector("abcdefg"), CStrVector("abcdefg*")));
EXPECT_TRUE(PassesFilter(CStrVector("abcdefg"), CStrVector("abc*")));
EXPECT_TRUE(PassesFilter(CStrVector("abcdefg"), CStrVector("*")));
EXPECT_TRUE(PassesFilter(CStrVector("abcdefg"), CStrVector("-~")));
EXPECT_TRUE(PassesFilter(CStrVector("abcdefg"), CStrVector("-abcdefgh")));
EXPECT_TRUE(PassesFilter(CStrVector("abdefg"), CStrVector("-")));
EXPECT_FALSE(PassesFilter(CStrVector("abcdefg"), CStrVector("-abcdefg")));
EXPECT_FALSE(PassesFilter(CStrVector("abcdefg"), CStrVector("-abcdefg*")));
EXPECT_FALSE(PassesFilter(CStrVector("abcdefg"), CStrVector("-abc*")));
EXPECT_FALSE(PassesFilter(CStrVector("abcdefg"), CStrVector("-*")));
EXPECT_FALSE(PassesFilter(CStrVector("abcdefg"), CStrVector("~")));
EXPECT_FALSE(PassesFilter(CStrVector("abcdefg"), CStrVector("")));
EXPECT_FALSE(PassesFilter(CStrVector("abcdefg"), CStrVector("abcdefgh")));
EXPECT_TRUE(PassesFilter(CStrVector(""), CStrVector("")));
EXPECT_TRUE(PassesFilter(CStrVector(""), CStrVector("*")));
EXPECT_FALSE(PassesFilter(CStrVector(""), CStrVector("-")));
EXPECT_FALSE(PassesFilter(CStrVector(""), CStrVector("-*")));
EXPECT_FALSE(PassesFilter(CStrVector(""), 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<size_t>::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