LCOV - code coverage report
Current view: top level - test/unittests/base - functional-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 87 87 100.0 %
Date: 2019-03-21 Functions: 199 291 68.4 %

          Line data    Source code
       1             : // Copyright 2014 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/base/functional.h"
       6             : 
       7             : #include <limits>
       8             : #include <set>
       9             : 
      10             : #include "test/unittests/test-utils.h"
      11             : 
      12             : namespace v8 {
      13             : namespace base {
      14             : 
      15       15373 : TEST(FunctionalTest, HashBool) {
      16             :   hash<bool> h, h1, h2;
      17           2 :   EXPECT_EQ(h1(true), h2(true));
      18           2 :   EXPECT_EQ(h1(false), h2(false));
      19           1 :   EXPECT_NE(h(true), h(false));
      20           1 : }
      21             : 
      22             : 
      23       15373 : TEST(FunctionalTest, HashFloatZero) {
      24             :   hash<float> h;
      25           2 :   EXPECT_EQ(h(0.0f), h(-0.0f));
      26           1 : }
      27             : 
      28             : 
      29       15373 : TEST(FunctionalTest, HashDoubleZero) {
      30             :   hash<double> h;
      31           2 :   EXPECT_EQ(h(0.0), h(-0.0));
      32           1 : }
      33             : 
      34             : namespace {
      35             : 
      36             : inline int64_t GetRandomSeedFromFlag(int random_seed) {
      37         140 :   return random_seed ? random_seed : TimeTicks::Now().ToInternalValue();
      38             : }
      39             : 
      40             : }  // namespace
      41             : 
      42             : template <typename T>
      43             : class FunctionalTest : public ::testing::Test {
      44             :  public:
      45         140 :   FunctionalTest()
      46         420 :       : rng_(GetRandomSeedFromFlag(::v8::internal::FLAG_random_seed)) {}
      47         140 :   ~FunctionalTest() override = default;
      48             : 
      49       10300 :   RandomNumberGenerator* rng() { return &rng_; }
      50             : 
      51             :  private:
      52             :   RandomNumberGenerator rng_;
      53             : 
      54             :   DISALLOW_COPY_AND_ASSIGN(FunctionalTest);
      55             : };
      56             : 
      57             : typedef ::testing::Types<signed char, unsigned char,
      58             :                          short,                    // NOLINT(runtime/int)
      59             :                          unsigned short,           // NOLINT(runtime/int)
      60             :                          int, unsigned int, long,  // NOLINT(runtime/int)
      61             :                          unsigned long,            // NOLINT(runtime/int)
      62             :                          long long,                // NOLINT(runtime/int)
      63             :                          unsigned long long,       // NOLINT(runtime/int)
      64             :                          int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
      65             :                          int64_t, uint64_t, float, double> FunctionalTypes;
      66             : 
      67             : TYPED_TEST_SUITE(FunctionalTest, FunctionalTypes);
      68             : 
      69       12376 : TYPED_TEST(FunctionalTest, EqualToImpliesSameHashCode) {
      70             :   hash<TypeParam> h;
      71             :   std::equal_to<TypeParam> e;
      72             :   TypeParam values[32];
      73          20 :   this->rng()->NextBytes(values, sizeof(values));
      74        2580 :   TRACED_FOREACH(TypeParam, v1, values) {
      75       82560 :     TRACED_FOREACH(TypeParam, v2, values) {
      76       20480 :       if (e(v1, v2)) {
      77        1928 :         EXPECT_EQ(h(v1), h(v2));
      78             :       }
      79             :     }
      80             :   }
      81          20 : }
      82             : 
      83             : 
      84       12376 : TYPED_TEST(FunctionalTest, HashEqualsHashValue) {
      85        5140 :   for (int i = 0; i < 128; ++i) {
      86             :     TypeParam v;
      87        2560 :     this->rng()->NextBytes(&v, sizeof(v));
      88             :     hash<TypeParam> h;
      89        8576 :     EXPECT_EQ(h(v), hash_value(v));
      90             :   }
      91          20 : }
      92             : 
      93             : 
      94       12376 : TYPED_TEST(FunctionalTest, HashIsStateless) {
      95             :   hash<TypeParam> h1, h2;
      96        5140 :   for (int i = 0; i < 128; ++i) {
      97             :     TypeParam v;
      98        2560 :     this->rng()->NextBytes(&v, sizeof(v));
      99        9216 :     EXPECT_EQ(h1(v), h2(v));
     100             :   }
     101          20 : }
     102             : 
     103             : 
     104       12376 : TYPED_TEST(FunctionalTest, HashIsOkish) {
     105             :   std::set<TypeParam> vs;
     106        5140 :   for (size_t i = 0; i < 128; ++i) {
     107             :     TypeParam v;
     108        2560 :     this->rng()->NextBytes(&v, sizeof(v));
     109             :     vs.insert(v);
     110             :   }
     111             :   std::set<size_t> hs;
     112        2434 :   for (const auto& v : vs) {
     113             :     hash<TypeParam> h;
     114        7242 :     hs.insert(h(v));
     115             :   }
     116          20 :   EXPECT_LE(vs.size() / 4u, hs.size());
     117          20 : }
     118             : 
     119             : 
     120       12376 : TYPED_TEST(FunctionalTest, HashValueArrayUsesHashRange) {
     121             :   TypeParam values[128];
     122          20 :   this->rng()->NextBytes(&values, sizeof(values));
     123          60 :   EXPECT_EQ(hash_range(values, values + arraysize(values)), hash_value(values));
     124          20 : }
     125             : 
     126             : 
     127       12376 : TYPED_TEST(FunctionalTest, BitEqualTo) {
     128             :   bit_equal_to<TypeParam> pred;
     129        5140 :   for (size_t i = 0; i < 128; ++i) {
     130             :     TypeParam v1, v2;
     131        2560 :     this->rng()->NextBytes(&v1, sizeof(v1));
     132        2560 :     this->rng()->NextBytes(&v2, sizeof(v2));
     133        2560 :     EXPECT_PRED2(pred, v1, v1);
     134        2560 :     EXPECT_PRED2(pred, v2, v2);
     135        5376 :     EXPECT_EQ(memcmp(&v1, &v2, sizeof(TypeParam)) == 0, pred(v1, v2));
     136             :   }
     137          20 : }
     138             : 
     139             : 
     140       12376 : TYPED_TEST(FunctionalTest, BitEqualToImpliesSameBitHash) {
     141             :   bit_hash<TypeParam> h;
     142             :   bit_equal_to<TypeParam> e;
     143             :   TypeParam values[32];
     144          20 :   this->rng()->NextBytes(&values, sizeof(values));
     145        2580 :   TRACED_FOREACH(TypeParam, v1, values) {
     146       82560 :     TRACED_FOREACH(TypeParam, v2, values) {
     147       20480 :       if (e(v1, v2)) {
     148        1928 :         EXPECT_EQ(h(v1), h(v2));
     149             :       }
     150             :     }
     151             :   }
     152          20 : }
     153             : 
     154             : 
     155             : namespace {
     156             : 
     157             : struct Foo {
     158             :   int x;
     159             :   double y;
     160             : };
     161             : 
     162             : 
     163          72 : size_t hash_value(Foo const& v) { return hash_combine(v.x, v.y); }
     164             : 
     165             : }  // namespace
     166             : 
     167             : 
     168       15373 : TEST(FunctionalTest, HashUsesArgumentDependentLookup) {
     169             :   const int kIntValues[] = {std::numeric_limits<int>::min(), -1, 0, 1, 42,
     170           1 :                             std::numeric_limits<int>::max()};
     171             :   const double kDoubleValues[] = {
     172             :       std::numeric_limits<double>::min(), -1, -0, 0, 1,
     173           1 :       std::numeric_limits<double>::max()};
     174          25 :   TRACED_FOREACH(int, x, kIntValues) {
     175         150 :     TRACED_FOREACH(double, y, kDoubleValues) {
     176             :       hash<Foo> h;
     177          36 :       Foo foo = {x, y};
     178         108 :       EXPECT_EQ(hash_combine(x, y), h(foo));
     179             :     }
     180             :   }
     181           1 : }
     182             : 
     183             : 
     184       15373 : TEST(FunctionalTest, BitEqualToFloat) {
     185             :   bit_equal_to<float> pred;
     186             :   EXPECT_FALSE(pred(0.0f, -0.0f));
     187             :   EXPECT_FALSE(pred(-0.0f, 0.0f));
     188           1 :   float const qNaN = std::numeric_limits<float>::quiet_NaN();
     189           1 :   float const sNaN = std::numeric_limits<float>::signaling_NaN();
     190           1 :   EXPECT_PRED2(pred, qNaN, qNaN);
     191           1 :   EXPECT_PRED2(pred, sNaN, sNaN);
     192           1 : }
     193             : 
     194             : 
     195       15373 : TEST(FunctionalTest, BitHashFloatDifferentForZeroAndMinusZero) {
     196             :   bit_hash<float> h;
     197           2 :   EXPECT_NE(h(0.0f), h(-0.0f));
     198           1 : }
     199             : 
     200             : 
     201       15373 : TEST(FunctionalTest, BitEqualToDouble) {
     202             :   bit_equal_to<double> pred;
     203             :   EXPECT_FALSE(pred(0.0, -0.0));
     204             :   EXPECT_FALSE(pred(-0.0, 0.0));
     205           1 :   double const qNaN = std::numeric_limits<double>::quiet_NaN();
     206           1 :   double const sNaN = std::numeric_limits<double>::signaling_NaN();
     207           1 :   EXPECT_PRED2(pred, qNaN, qNaN);
     208           1 :   EXPECT_PRED2(pred, sNaN, sNaN);
     209           1 : }
     210             : 
     211             : 
     212       15373 : TEST(FunctionalTest, BitHashDoubleDifferentForZeroAndMinusZero) {
     213             :   bit_hash<double> h;
     214           2 :   EXPECT_NE(h(0.0), h(-0.0));
     215           1 : }
     216             : 
     217             : }  // namespace base
     218        9222 : }  // namespace v8

Generated by: LCOV version 1.10