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