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