UtilsTest.cpp revision 0a657bbc2c6fc9daf699942e023050536d5ec95f
1 2/* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8#include "Test.h" 9#include "SkRandom.h" 10#include "SkRefCnt.h" 11#include "SkTSearch.h" 12#include "SkTSort.h" 13#include "SkUtils.h" 14 15class RefClass : public SkRefCnt { 16public: 17 SK_DECLARE_INST_COUNT(RefClass) 18 19 RefClass(int n) : fN(n) {} 20 int get() const { return fN; } 21 22private: 23 int fN; 24 25 typedef SkRefCnt INHERITED; 26}; 27 28SK_DEFINE_INST_COUNT(RefClass) 29 30static void test_autounref(skiatest::Reporter* reporter) { 31 RefClass obj(0); 32 REPORTER_ASSERT(reporter, 1 == obj.getRefCnt()); 33 34 SkAutoTUnref<RefClass> tmp(&obj); 35 REPORTER_ASSERT(reporter, &obj == tmp.get()); 36 REPORTER_ASSERT(reporter, 1 == obj.getRefCnt()); 37 38 REPORTER_ASSERT(reporter, &obj == tmp.detach()); 39 REPORTER_ASSERT(reporter, 1 == obj.getRefCnt()); 40 REPORTER_ASSERT(reporter, NULL == tmp.detach()); 41 REPORTER_ASSERT(reporter, NULL == tmp.get()); 42 43 obj.ref(); 44 REPORTER_ASSERT(reporter, 2 == obj.getRefCnt()); 45 { 46 SkAutoTUnref<RefClass> tmp2(&obj); 47 } 48 REPORTER_ASSERT(reporter, 1 == obj.getRefCnt()); 49} 50 51static void test_autostarray(skiatest::Reporter* reporter) { 52 RefClass obj0(0); 53 RefClass obj1(1); 54 REPORTER_ASSERT(reporter, 1 == obj0.getRefCnt()); 55 REPORTER_ASSERT(reporter, 1 == obj1.getRefCnt()); 56 57 { 58 SkAutoSTArray<2, SkRefPtr<RefClass> > tmp; 59 REPORTER_ASSERT(reporter, 0 == tmp.count()); 60 61 tmp.reset(0); // test out reset(0) when already at 0 62 tmp.reset(4); // this should force a new allocation 63 REPORTER_ASSERT(reporter, 4 == tmp.count()); 64 tmp[0] = &obj0; 65 tmp[1] = &obj1; 66 REPORTER_ASSERT(reporter, 2 == obj0.getRefCnt()); 67 REPORTER_ASSERT(reporter, 2 == obj1.getRefCnt()); 68 69 // test out reset with data in the array (and a new allocation) 70 tmp.reset(0); 71 REPORTER_ASSERT(reporter, 0 == tmp.count()); 72 REPORTER_ASSERT(reporter, 1 == obj0.getRefCnt()); 73 REPORTER_ASSERT(reporter, 1 == obj1.getRefCnt()); 74 75 tmp.reset(2); // this should use the preexisting allocation 76 REPORTER_ASSERT(reporter, 2 == tmp.count()); 77 tmp[0] = &obj0; 78 tmp[1] = &obj1; 79 } 80 81 // test out destructor with data in the array (and using existing allocation) 82 REPORTER_ASSERT(reporter, 1 == obj0.getRefCnt()); 83 REPORTER_ASSERT(reporter, 1 == obj1.getRefCnt()); 84 85 { 86 // test out allocating ctor (this should allocate new memory) 87 SkAutoSTArray<2, SkRefPtr<RefClass> > tmp(4); 88 REPORTER_ASSERT(reporter, 4 == tmp.count()); 89 90 tmp[0] = &obj0; 91 tmp[1] = &obj1; 92 REPORTER_ASSERT(reporter, 2 == obj0.getRefCnt()); 93 REPORTER_ASSERT(reporter, 2 == obj1.getRefCnt()); 94 95 // Test out resut with data in the array and malloced storage 96 tmp.reset(0); 97 REPORTER_ASSERT(reporter, 1 == obj0.getRefCnt()); 98 REPORTER_ASSERT(reporter, 1 == obj1.getRefCnt()); 99 100 tmp.reset(2); // this should use the preexisting storage 101 tmp[0] = &obj0; 102 tmp[1] = &obj1; 103 REPORTER_ASSERT(reporter, 2 == obj0.getRefCnt()); 104 REPORTER_ASSERT(reporter, 2 == obj1.getRefCnt()); 105 106 tmp.reset(4); // this should force a new malloc 107 REPORTER_ASSERT(reporter, 1 == obj0.getRefCnt()); 108 REPORTER_ASSERT(reporter, 1 == obj1.getRefCnt()); 109 110 tmp[0] = &obj0; 111 tmp[1] = &obj1; 112 REPORTER_ASSERT(reporter, 2 == obj0.getRefCnt()); 113 REPORTER_ASSERT(reporter, 2 == obj1.getRefCnt()); 114 } 115 116 REPORTER_ASSERT(reporter, 1 == obj0.getRefCnt()); 117 REPORTER_ASSERT(reporter, 1 == obj1.getRefCnt()); 118} 119 120///////////////////////////////////////////////////////////////////////////// 121 122#define kSEARCH_COUNT 91 123 124static void test_search(skiatest::Reporter* reporter) { 125 int i, array[kSEARCH_COUNT]; 126 SkRandom rand; 127 128 for (i = 0; i < kSEARCH_COUNT; i++) { 129 array[i] = rand.nextS(); 130 } 131 132 SkTHeapSort<int>(array, kSEARCH_COUNT); 133 // make sure we got sorted properly 134 for (i = 1; i < kSEARCH_COUNT; i++) { 135 REPORTER_ASSERT(reporter, array[i-1] <= array[i]); 136 } 137 138 // make sure we can find all of our values 139 for (i = 0; i < kSEARCH_COUNT; i++) { 140 int index = SkTSearch<int>(array, kSEARCH_COUNT, array[i], sizeof(int)); 141 REPORTER_ASSERT(reporter, index == i); 142 } 143 144 // make sure that random values are either found, or the correct 145 // insertion index is returned 146 for (i = 0; i < 10000; i++) { 147 int value = rand.nextS(); 148 int index = SkTSearch<int>(array, kSEARCH_COUNT, value, sizeof(int)); 149 150 if (index >= 0) { 151 REPORTER_ASSERT(reporter, 152 index < kSEARCH_COUNT && array[index] == value); 153 } else { 154 index = ~index; 155 REPORTER_ASSERT(reporter, index <= kSEARCH_COUNT); 156 if (index < kSEARCH_COUNT) { 157 REPORTER_ASSERT(reporter, value < array[index]); 158 if (index > 0) { 159 REPORTER_ASSERT(reporter, value > array[index - 1]); 160 } 161 } else { 162 // we should append the new value 163 REPORTER_ASSERT(reporter, value > array[kSEARCH_COUNT - 1]); 164 } 165 } 166 } 167} 168 169static void test_utf16(skiatest::Reporter* reporter) { 170 static const SkUnichar gUni[] = { 171 0x10000, 0x18080, 0x20202, 0xFFFFF, 0x101234 172 }; 173 174 uint16_t buf[2]; 175 176 for (size_t i = 0; i < SK_ARRAY_COUNT(gUni); i++) { 177 size_t count = SkUTF16_FromUnichar(gUni[i], buf); 178 REPORTER_ASSERT(reporter, count == 2); 179 size_t count2 = SkUTF16_CountUnichars(buf, 2); 180 REPORTER_ASSERT(reporter, count2 == 1); 181 const uint16_t* ptr = buf; 182 SkUnichar c = SkUTF16_NextUnichar(&ptr); 183 REPORTER_ASSERT(reporter, c == gUni[i]); 184 REPORTER_ASSERT(reporter, ptr - buf == 2); 185 } 186} 187 188static void TestUTF(skiatest::Reporter* reporter) { 189 static const struct { 190 const char* fUtf8; 191 SkUnichar fUni; 192 } gTest[] = { 193 { "a", 'a' }, 194 { "\x7f", 0x7f }, 195 { "\xC2\x80", 0x80 }, 196 { "\xC3\x83", (3 << 6) | 3 }, 197 { "\xDF\xBF", 0x7ff }, 198 { "\xE0\xA0\x80", 0x800 }, 199 { "\xE0\xB0\xB8", 0xC38 }, 200 { "\xE3\x83\x83", (3 << 12) | (3 << 6) | 3 }, 201 { "\xEF\xBF\xBF", 0xFFFF }, 202 { "\xF0\x90\x80\x80", 0x10000 }, 203 { "\xF3\x83\x83\x83", (3 << 18) | (3 << 12) | (3 << 6) | 3 } 204 }; 205 206 for (size_t i = 0; i < SK_ARRAY_COUNT(gTest); i++) { 207 const char* p = gTest[i].fUtf8; 208 int n = SkUTF8_CountUnichars(p); 209 SkUnichar u0 = SkUTF8_ToUnichar(gTest[i].fUtf8); 210 SkUnichar u1 = SkUTF8_NextUnichar(&p); 211 212 REPORTER_ASSERT(reporter, n == 1); 213 REPORTER_ASSERT(reporter, u0 == u1); 214 REPORTER_ASSERT(reporter, u0 == gTest[i].fUni); 215 REPORTER_ASSERT(reporter, 216 p - gTest[i].fUtf8 == (int)strlen(gTest[i].fUtf8)); 217 } 218 219 test_utf16(reporter); 220 test_search(reporter); 221 test_autounref(reporter); 222 test_autostarray(reporter); 223} 224 225#include "TestClassDef.h" 226DEFINE_TESTCLASS("Utils", UtfTestClass, TestUTF) 227