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 <limits.h> 37#include <string.h> 38 39namespace WTF { 40 41TEST(ArrayBufferBuilderTest, Constructor) 42{ 43 ArrayBufferBuilder zeroBuilder(0); 44 EXPECT_EQ(0u, zeroBuilder.byteLength()); 45 EXPECT_EQ(0u, zeroBuilder.capacity()); 46 47 ArrayBufferBuilder smallBuilder(1024); 48 EXPECT_EQ(0u, zeroBuilder.byteLength()); 49 EXPECT_EQ(1024u, smallBuilder.capacity()); 50 51 ArrayBufferBuilder bigBuilder(2048); 52 EXPECT_EQ(0u, zeroBuilder.byteLength()); 53 EXPECT_EQ(2048u, bigBuilder.capacity()); 54} 55 56TEST(ArrayBufferBuilderTest, Append) 57{ 58 const char data[] = "HelloWorld"; 59 size_t dataSize = sizeof(data) - 1; 60 61 ArrayBufferBuilder builder(2 * dataSize); 62 63 EXPECT_EQ(dataSize, builder.append(data, dataSize)); 64 EXPECT_EQ(dataSize, builder.byteLength()); 65 EXPECT_EQ(dataSize * 2, builder.capacity()); 66 67 EXPECT_EQ(dataSize, builder.append(data, dataSize)); 68 EXPECT_EQ(dataSize * 2, builder.byteLength()); 69 EXPECT_EQ(dataSize * 2, builder.capacity()); 70 71 EXPECT_EQ(dataSize, builder.append(data, dataSize)); 72 EXPECT_EQ(dataSize * 3, builder.byteLength()); 73 EXPECT_GE(builder.capacity(), dataSize * 3); 74} 75 76TEST(ArrayBufferBuilderTest, AppendRepeatedly) 77{ 78 const char data[] = "HelloWorld"; 79 size_t dataSize = sizeof(data) - 1; 80 81 ArrayBufferBuilder builder(37); // Some number coprime with dataSize. 82 83 for (size_t i = 1; i < 1000U; ++i) { 84 EXPECT_EQ(dataSize, builder.append(data, dataSize)); 85 EXPECT_EQ(dataSize * i, builder.byteLength()); 86 EXPECT_GE(builder.capacity(), dataSize * i); 87 } 88} 89 90TEST(ArrayBufferBuilderTest, DefaultConstructorAndAppendRepeatedly) 91{ 92 const char data[] = "HelloWorld"; 93 size_t dataSize = sizeof(data) - 1; 94 95 ArrayBufferBuilder builder; 96 97 for (size_t i = 1; i < 4000U; ++i) { 98 EXPECT_EQ(dataSize, builder.append(data, dataSize)); 99 EXPECT_EQ(dataSize * i, builder.byteLength()); 100 EXPECT_GE(builder.capacity(), dataSize * i); 101 } 102} 103 104TEST(ArrayBufferBuilderTest, AppendFixedCapacity) 105{ 106 const char data[] = "HelloWorld"; 107 size_t dataSize = sizeof(data) - 1; 108 109 ArrayBufferBuilder builder(15); 110 builder.setVariableCapacity(false); 111 112 EXPECT_EQ(dataSize, builder.append(data, dataSize)); 113 EXPECT_EQ(dataSize, builder.byteLength()); 114 EXPECT_EQ(15u, builder.capacity()); 115 116 EXPECT_EQ(5u, builder.append(data, dataSize)); 117 EXPECT_EQ(15u, builder.byteLength()); 118 EXPECT_EQ(15u, builder.capacity()); 119 120 EXPECT_EQ(0u, builder.append(data, dataSize)); 121 EXPECT_EQ(15u, builder.byteLength()); 122 EXPECT_EQ(15u, builder.capacity()); 123} 124 125TEST(ArrayBufferBuilderTest, ToArrayBuffer) 126{ 127 const char data1[] = "HelloWorld"; 128 size_t data1Size = sizeof(data1) - 1; 129 130 const char data2[] = "GoodbyeWorld"; 131 size_t data2Size = sizeof(data2) - 1; 132 133 ArrayBufferBuilder builder(1024); 134 builder.append(data1, data1Size); 135 builder.append(data2, data2Size); 136 137 const char expected[] = "HelloWorldGoodbyeWorld"; 138 size_t expectedSize = sizeof(expected) - 1; 139 140 RefPtr<ArrayBuffer> result = builder.toArrayBuffer(); 141 ASSERT_EQ(data1Size + data2Size, result->byteLength()); 142 ASSERT_EQ(expectedSize, result->byteLength()); 143 EXPECT_EQ(0, memcmp(expected, result->data(), expectedSize)); 144} 145 146TEST(ArrayBufferBuilderTest, ToArrayBufferSameAddressIfExactCapacity) 147{ 148 const char data[] = "HelloWorld"; 149 size_t dataSize = sizeof(data) - 1; 150 151 ArrayBufferBuilder builder(dataSize); 152 builder.append(data, dataSize); 153 154 RefPtr<ArrayBuffer> result1 = builder.toArrayBuffer(); 155 RefPtr<ArrayBuffer> result2 = builder.toArrayBuffer(); 156 EXPECT_EQ(result1.get(), result2.get()); 157} 158 159TEST(ArrayBufferBuilderTest, ToString) 160{ 161 const char data1[] = "HelloWorld"; 162 size_t data1Size = sizeof(data1) - 1; 163 164 const char data2[] = "GoodbyeWorld"; 165 size_t data2Size = sizeof(data2) - 1; 166 167 ArrayBufferBuilder builder(1024); 168 builder.append(data1, data1Size); 169 builder.append(data2, data2Size); 170 171 const char expected[] = "HelloWorldGoodbyeWorld"; 172 size_t expectedSize = sizeof(expected) - 1; 173 174 String result = builder.toString(); 175 EXPECT_EQ(expectedSize, result.length()); 176 for (unsigned i = 0; i < result.length(); ++i) 177 EXPECT_EQ(expected[i], result[i]); 178} 179 180TEST(ArrayBufferBuilderTest, ShrinkToFitNoAppend) 181{ 182 ArrayBufferBuilder builder(1024); 183 EXPECT_EQ(1024u, builder.capacity()); 184 builder.shrinkToFit(); 185 EXPECT_EQ(0u, builder.byteLength()); 186 EXPECT_EQ(0u, builder.capacity()); 187} 188 189TEST(ArrayBufferBuilderTest, ShrinkToFit) 190{ 191 const char data[] = "HelloWorld"; 192 size_t dataSize = sizeof(data) - 1; 193 194 ArrayBufferBuilder builder(32); 195 196 EXPECT_EQ(dataSize, builder.append(data, dataSize)); 197 EXPECT_EQ(dataSize, builder.byteLength()); 198 EXPECT_EQ(32u, builder.capacity()); 199 200 builder.shrinkToFit(); 201 EXPECT_EQ(dataSize, builder.byteLength()); 202 EXPECT_EQ(dataSize, builder.capacity()); 203} 204 205TEST(ArrayBufferBuilderTest, ShrinkToFitFullyUsed) 206{ 207 const char data[] = "HelloWorld"; 208 size_t dataSize = sizeof(data) - 1; 209 210 ArrayBufferBuilder builder(dataSize); 211 const void* internalAddress = builder.data(); 212 213 EXPECT_EQ(dataSize, builder.append(data, dataSize)); 214 EXPECT_EQ(dataSize, builder.byteLength()); 215 EXPECT_EQ(dataSize, builder.capacity()); 216 217 builder.shrinkToFit(); 218 // Reallocation should not happen. 219 EXPECT_EQ(internalAddress, builder.data()); 220 EXPECT_EQ(dataSize, builder.byteLength()); 221 EXPECT_EQ(dataSize, builder.capacity()); 222} 223 224TEST(ArrayBufferBuilderTest, ShrinkToFitAfterGrowth) 225{ 226 const char data[] = "HelloWorld"; 227 size_t dataSize = sizeof(data) - 1; 228 229 ArrayBufferBuilder builder(5); 230 231 EXPECT_EQ(dataSize, builder.append(data, dataSize)); 232 EXPECT_GE(builder.capacity(), dataSize); 233 builder.shrinkToFit(); 234 EXPECT_EQ(dataSize, builder.byteLength()); 235 EXPECT_EQ(dataSize, builder.capacity()); 236} 237 238} // namespace WTF 239