LCOV - code coverage report
Current view: top level - test/unittests/base - functional-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 88 88 100.0 %
Date: 2019-01-20 Functions: 199 315 63.2 %

          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       15128 : 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       15128 : TEST(FunctionalTest, HashFloatZero) {
      24             :   hash<float> h;
      25           2 :   EXPECT_EQ(h(0.0f), h(-0.0f));
      26           1 : }
      27             : 
      28             : 
      29       15128 : 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         280 :   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             :   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_CASE(FunctionalTest, FunctionalTypes);
      68             : 
      69             : 
      70       12180 : TYPED_TEST(FunctionalTest, EqualToImpliesSameHashCode) {
      71             :   hash<TypeParam> h;
      72             :   std::equal_to<TypeParam> e;
      73             :   TypeParam values[32];
      74          20 :   this->rng()->NextBytes(values, sizeof(values));
      75        2580 :   TRACED_FOREACH(TypeParam, v1, values) {
      76      102400 :     TRACED_FOREACH(TypeParam, v2, values) {
      77       20480 :       if (e(v1, v2)) {
      78        1856 :         EXPECT_EQ(h(v1), h(v2));
      79             :       }
      80             :     }
      81             :   }
      82          20 : }
      83             : 
      84             : 
      85       12180 : TYPED_TEST(FunctionalTest, HashEqualsHashValue) {
      86        2580 :   for (int i = 0; i < 128; ++i) {
      87             :     TypeParam v;
      88        2560 :     this->rng()->NextBytes(&v, sizeof(v));
      89             :     hash<TypeParam> h;
      90        8576 :     EXPECT_EQ(h(v), hash_value(v));
      91             :   }
      92          20 : }
      93             : 
      94             : 
      95       12180 : TYPED_TEST(FunctionalTest, HashIsStateless) {
      96             :   hash<TypeParam> h1, h2;
      97        2580 :   for (int i = 0; i < 128; ++i) {
      98             :     TypeParam v;
      99        2560 :     this->rng()->NextBytes(&v, sizeof(v));
     100        9216 :     EXPECT_EQ(h1(v), h2(v));
     101             :   }
     102          20 : }
     103             : 
     104             : 
     105       12180 : TYPED_TEST(FunctionalTest, HashIsOkish) {
     106             :   std::set<TypeParam> vs;
     107        2580 :   for (size_t i = 0; i < 128; ++i) {
     108             :     TypeParam v;
     109        2560 :     this->rng()->NextBytes(&v, sizeof(v));
     110             :     vs.insert(v);
     111             :   }
     112             :   std::set<size_t> hs;
     113        2492 :   for (const auto& v : vs) {
     114             :     hash<TypeParam> h;
     115        7356 :     hs.insert(h(v));
     116             :   }
     117          40 :   EXPECT_LE(vs.size() / 4u, hs.size());
     118          20 : }
     119             : 
     120             : 
     121       12180 : TYPED_TEST(FunctionalTest, HashValueArrayUsesHashRange) {
     122             :   TypeParam values[128];
     123          20 :   this->rng()->NextBytes(&values, sizeof(values));
     124          60 :   EXPECT_EQ(hash_range(values, values + arraysize(values)), hash_value(values));
     125          20 : }
     126             : 
     127             : 
     128       12180 : TYPED_TEST(FunctionalTest, BitEqualTo) {
     129             :   bit_equal_to<TypeParam> pred;
     130        2580 :   for (size_t i = 0; i < 128; ++i) {
     131             :     TypeParam v1, v2;
     132        2560 :     this->rng()->NextBytes(&v1, sizeof(v1));
     133        2560 :     this->rng()->NextBytes(&v2, sizeof(v2));
     134        2560 :     EXPECT_PRED2(pred, v1, v1);
     135        2560 :     EXPECT_PRED2(pred, v2, v2);
     136        7680 :     EXPECT_EQ(memcmp(&v1, &v2, sizeof(TypeParam)) == 0, pred(v1, v2));
     137             :   }
     138          20 : }
     139             : 
     140             : 
     141       12180 : TYPED_TEST(FunctionalTest, BitEqualToImpliesSameBitHash) {
     142             :   bit_hash<TypeParam> h;
     143             :   bit_equal_to<TypeParam> e;
     144             :   TypeParam values[32];
     145          20 :   this->rng()->NextBytes(&values, sizeof(values));
     146        2580 :   TRACED_FOREACH(TypeParam, v1, values) {
     147      102400 :     TRACED_FOREACH(TypeParam, v2, values) {
     148       20480 :       if (e(v1, v2)) {
     149        1856 :         EXPECT_EQ(h(v1), h(v2));
     150             :       }
     151             :     }
     152             :   }
     153          20 : }
     154             : 
     155             : 
     156             : namespace {
     157             : 
     158             : struct Foo {
     159             :   int x;
     160             :   double y;
     161             : };
     162             : 
     163             : 
     164          72 : size_t hash_value(Foo const& v) { return hash_combine(v.x, v.y); }
     165             : 
     166             : }  // namespace
     167             : 
     168             : 
     169       15128 : TEST(FunctionalTest, HashUsesArgumentDependentLookup) {
     170             :   const int kIntValues[] = {std::numeric_limits<int>::min(), -1, 0, 1, 42,
     171           1 :                             std::numeric_limits<int>::max()};
     172             :   const double kDoubleValues[] = {
     173             :       std::numeric_limits<double>::min(), -1, -0, 0, 1,
     174           1 :       std::numeric_limits<double>::max()};
     175          37 :   TRACED_FOREACH(int, x, kIntValues) {
     176         252 :     TRACED_FOREACH(double, y, kDoubleValues) {
     177             :       hash<Foo> h;
     178          36 :       Foo foo = {x, y};
     179         108 :       EXPECT_EQ(hash_combine(x, y), h(foo));
     180          36 :     }
     181           6 :   }
     182           1 : }
     183             : 
     184             : 
     185       15128 : TEST(FunctionalTest, BitEqualToFloat) {
     186             :   bit_equal_to<float> pred;
     187             :   EXPECT_FALSE(pred(0.0f, -0.0f));
     188             :   EXPECT_FALSE(pred(-0.0f, 0.0f));
     189           1 :   float const qNaN = std::numeric_limits<float>::quiet_NaN();
     190           1 :   float const sNaN = std::numeric_limits<float>::signaling_NaN();
     191           1 :   EXPECT_PRED2(pred, qNaN, qNaN);
     192           1 :   EXPECT_PRED2(pred, sNaN, sNaN);
     193           1 : }
     194             : 
     195             : 
     196       15128 : TEST(FunctionalTest, BitHashFloatDifferentForZeroAndMinusZero) {
     197             :   bit_hash<float> h;
     198           2 :   EXPECT_NE(h(0.0f), h(-0.0f));
     199           1 : }
     200             : 
     201             : 
     202       15128 : TEST(FunctionalTest, BitEqualToDouble) {
     203             :   bit_equal_to<double> pred;
     204             :   EXPECT_FALSE(pred(0.0, -0.0));
     205             :   EXPECT_FALSE(pred(-0.0, 0.0));
     206           1 :   double const qNaN = std::numeric_limits<double>::quiet_NaN();
     207           1 :   double const sNaN = std::numeric_limits<double>::signaling_NaN();
     208           1 :   EXPECT_PRED2(pred, qNaN, qNaN);
     209           1 :   EXPECT_PRED2(pred, sNaN, sNaN);
     210           1 : }
     211             : 
     212             : 
     213       15128 : TEST(FunctionalTest, BitHashDoubleDifferentForZeroAndMinusZero) {
     214             :   bit_hash<double> h;
     215           2 :   EXPECT_NE(h(0.0), h(-0.0));
     216           1 : }
     217             : 
     218             : }  // namespace base
     219        9075 : }  // namespace v8

Generated by: LCOV version 1.10