Home | History | Annotate | Download | only in wtf
      1 /*
      2  * Copyright (C) 2013 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "wtf/ArrayBufferBuilder.h"
     33 
     34 #include "wtf/Assertions.h"
     35 #include <gtest/gtest.h>
     36 #include <string.h>
     37 
     38 namespace WTF {
     39 
     40 TEST(ArrayBufferBuilder, Constructor)
     41 {
     42     ArrayBufferBuilder zeroBuilder(0);
     43     EXPECT_EQ(0u, zeroBuilder.byteLength());
     44     EXPECT_EQ(0u, zeroBuilder.capacity());
     45 
     46     ArrayBufferBuilder smallBuilder(1024);
     47     EXPECT_EQ(0u, zeroBuilder.byteLength());
     48     EXPECT_EQ(1024u, smallBuilder.capacity());
     49 
     50     ArrayBufferBuilder bigBuilder(2048);
     51     EXPECT_EQ(0u, zeroBuilder.byteLength());
     52     EXPECT_EQ(2048u, bigBuilder.capacity());
     53 }
     54 
     55 TEST(ArrayBufferBuilder, Append)
     56 {
     57     const char data[] = "HelloWorld";
     58     size_t dataSize = sizeof(data) - 1;
     59 
     60     ArrayBufferBuilder builder(2 * dataSize);
     61 
     62     EXPECT_EQ(dataSize, builder.append(data, dataSize));
     63     EXPECT_EQ(dataSize, builder.byteLength());
     64     EXPECT_EQ(dataSize * 2, builder.capacity());
     65 
     66     EXPECT_EQ(dataSize, builder.append(data, dataSize));
     67     EXPECT_EQ(dataSize * 2, builder.byteLength());
     68     EXPECT_EQ(dataSize * 2, builder.capacity());
     69 
     70     EXPECT_EQ(dataSize, builder.append(data, dataSize));
     71     EXPECT_EQ(dataSize * 3, builder.byteLength());
     72     EXPECT_GE(builder.capacity(), dataSize * 3);
     73 }
     74 
     75 TEST(ArrayBufferBuilder, AppendRepeatedly)
     76 {
     77     const char data[] = "HelloWorld";
     78     size_t dataSize = sizeof(data) - 1;
     79 
     80     ArrayBufferBuilder builder(37); // Some number coprime with dataSize.
     81 
     82     for (size_t i = 1; i < 1000U; ++i) {
     83         EXPECT_EQ(dataSize, builder.append(data, dataSize));
     84         EXPECT_EQ(dataSize * i, builder.byteLength());
     85         EXPECT_GE(builder.capacity(), dataSize * i);
     86     }
     87 }
     88 
     89 TEST(ArrayBufferBuilder, DefaultConstructorAndAppendRepeatedly)
     90 {
     91     const char data[] = "HelloWorld";
     92     size_t dataSize = sizeof(data) - 1;
     93 
     94     ArrayBufferBuilder builder;
     95 
     96     for (size_t i = 1; i < 4000U; ++i) {
     97         EXPECT_EQ(dataSize, builder.append(data, dataSize));
     98         EXPECT_EQ(dataSize * i, builder.byteLength());
     99         EXPECT_GE(builder.capacity(), dataSize * i);
    100     }
    101 }
    102 
    103 TEST(ArrayBufferBuilder, AppendFixedCapacity)
    104 {
    105     const char data[] = "HelloWorld";
    106     size_t dataSize = sizeof(data) - 1;
    107 
    108     ArrayBufferBuilder builder(15);
    109     builder.setVariableCapacity(false);
    110 
    111     EXPECT_EQ(dataSize, builder.append(data, dataSize));
    112     EXPECT_EQ(dataSize, builder.byteLength());
    113     EXPECT_EQ(15u, builder.capacity());
    114 
    115     EXPECT_EQ(5u, builder.append(data, dataSize));
    116     EXPECT_EQ(15u, builder.byteLength());
    117     EXPECT_EQ(15u, builder.capacity());
    118 
    119     EXPECT_EQ(0u, builder.append(data, dataSize));
    120     EXPECT_EQ(15u, builder.byteLength());
    121     EXPECT_EQ(15u, builder.capacity());
    122 }
    123 
    124 TEST(ArrayBufferBuilder, ToArrayBuffer)
    125 {
    126     const char data1[] = "HelloWorld";
    127     size_t data1Size = sizeof(data1) - 1;
    128 
    129     const char data2[] = "GoodbyeWorld";
    130     size_t data2Size = sizeof(data2) - 1;
    131 
    132     ArrayBufferBuilder builder(1024);
    133     builder.append(data1, data1Size);
    134     builder.append(data2, data2Size);
    135 
    136     const char expected[] = "HelloWorldGoodbyeWorld";
    137     size_t expectedSize = sizeof(expected) - 1;
    138 
    139     RefPtr<ArrayBuffer> result = builder.toArrayBuffer();
    140     ASSERT_EQ(data1Size + data2Size, result->byteLength());
    141     ASSERT_EQ(expectedSize, result->byteLength());
    142     EXPECT_EQ(0, memcmp(expected, result->data(), expectedSize));
    143 }
    144 
    145 TEST(ArrayBufferBuilder, ToArrayBufferSameAddressIfExactCapacity)
    146 {
    147     const char data[] = "HelloWorld";
    148     size_t dataSize = sizeof(data) - 1;
    149 
    150     ArrayBufferBuilder builder(dataSize);
    151     builder.append(data, dataSize);
    152 
    153     RefPtr<ArrayBuffer> result1 = builder.toArrayBuffer();
    154     RefPtr<ArrayBuffer> result2 = builder.toArrayBuffer();
    155     EXPECT_EQ(result1.get(), result2.get());
    156 }
    157 
    158 TEST(ArrayBufferBuilder, ToString)
    159 {
    160     const char data1[] = "HelloWorld";
    161     size_t data1Size = sizeof(data1) - 1;
    162 
    163     const char data2[] = "GoodbyeWorld";
    164     size_t data2Size = sizeof(data2) - 1;
    165 
    166     ArrayBufferBuilder builder(1024);
    167     builder.append(data1, data1Size);
    168     builder.append(data2, data2Size);
    169 
    170     const char expected[] = "HelloWorldGoodbyeWorld";
    171     size_t expectedSize = sizeof(expected) - 1;
    172 
    173     String result = builder.toString();
    174     EXPECT_EQ(expectedSize, result.length());
    175     for (unsigned i = 0; i < result.length(); ++i)
    176         EXPECT_EQ(expected[i], result[i]);
    177 }
    178 
    179 TEST(ArrayBufferBuilder, ShrinkToFitNoAppend)
    180 {
    181     ArrayBufferBuilder builder(1024);
    182     EXPECT_EQ(1024u, builder.capacity());
    183     builder.shrinkToFit();
    184     EXPECT_EQ(0u, builder.byteLength());
    185     EXPECT_EQ(0u, builder.capacity());
    186 }
    187 
    188 TEST(ArrayBufferBuilder, ShrinkToFit)
    189 {
    190     const char data[] = "HelloWorld";
    191     size_t dataSize = sizeof(data) - 1;
    192 
    193     ArrayBufferBuilder builder(32);
    194 
    195     EXPECT_EQ(dataSize, builder.append(data, dataSize));
    196     EXPECT_EQ(dataSize, builder.byteLength());
    197     EXPECT_EQ(32u, builder.capacity());
    198 
    199     builder.shrinkToFit();
    200     EXPECT_EQ(dataSize, builder.byteLength());
    201     EXPECT_EQ(dataSize, builder.capacity());
    202 }
    203 
    204 TEST(ArrayBufferBuilder, ShrinkToFitFullyUsed)
    205 {
    206     const char data[] = "HelloWorld";
    207     size_t dataSize = sizeof(data) - 1;
    208 
    209     ArrayBufferBuilder builder(dataSize);
    210     const void* internalAddress = builder.data();
    211 
    212     EXPECT_EQ(dataSize, builder.append(data, dataSize));
    213     EXPECT_EQ(dataSize, builder.byteLength());
    214     EXPECT_EQ(dataSize, builder.capacity());
    215 
    216     builder.shrinkToFit();
    217     // Reallocation should not happen.
    218     EXPECT_EQ(internalAddress, builder.data());
    219     EXPECT_EQ(dataSize, builder.byteLength());
    220     EXPECT_EQ(dataSize, builder.capacity());
    221 }
    222 
    223 TEST(ArrayBufferBuilder, ShrinkToFitAfterGrowth)
    224 {
    225     const char data[] = "HelloWorld";
    226     size_t dataSize = sizeof(data) - 1;
    227 
    228     ArrayBufferBuilder builder(5);
    229 
    230     EXPECT_EQ(dataSize, builder.append(data, dataSize));
    231     EXPECT_GE(builder.capacity(), dataSize);
    232     builder.shrinkToFit();
    233     EXPECT_EQ(dataSize, builder.byteLength());
    234     EXPECT_EQ(dataSize, builder.capacity());
    235 }
    236 
    237 } // namespace WTF
    238