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 "SkRandom.h"
      9 #include "SkRefCnt.h"
     10 #include "SkTSearch.h"
     11 #include "SkTSort.h"
     12 #include "SkUtils.h"
     13 #include "Test.h"
     14 
     15 class RefClass : public SkRefCnt {
     16 public:
     17 
     18 
     19     RefClass(int n) : fN(n) {}
     20     int get() const { return fN; }
     21 
     22 private:
     23     int fN;
     24 
     25     typedef SkRefCnt INHERITED;
     26 };
     27 
     28 static void test_autounref(skiatest::Reporter* reporter) {
     29     RefClass obj(0);
     30     REPORTER_ASSERT(reporter, obj.unique());
     31 
     32     sk_sp<RefClass> tmp(&obj);
     33     REPORTER_ASSERT(reporter, &obj == tmp.get());
     34     REPORTER_ASSERT(reporter, obj.unique());
     35 
     36     REPORTER_ASSERT(reporter, &obj == tmp.release());
     37     REPORTER_ASSERT(reporter, obj.unique());
     38     REPORTER_ASSERT(reporter, nullptr == tmp.release());
     39     REPORTER_ASSERT(reporter, nullptr == tmp.get());
     40 
     41     obj.ref();
     42     REPORTER_ASSERT(reporter, !obj.unique());
     43     {
     44         sk_sp<RefClass> tmp2(&obj);
     45     }
     46     REPORTER_ASSERT(reporter, obj.unique());
     47 }
     48 
     49 static void test_autostarray(skiatest::Reporter* reporter) {
     50     RefClass obj0(0);
     51     RefClass obj1(1);
     52     REPORTER_ASSERT(reporter, obj0.unique());
     53     REPORTER_ASSERT(reporter, obj1.unique());
     54 
     55     {
     56         SkAutoSTArray<2, sk_sp<RefClass> > tmp;
     57         REPORTER_ASSERT(reporter, 0 == tmp.count());
     58 
     59         tmp.reset(0);   // test out reset(0) when already at 0
     60         tmp.reset(4);   // this should force a new allocation
     61         REPORTER_ASSERT(reporter, 4 == tmp.count());
     62         tmp[0].reset(SkRef(&obj0));
     63         tmp[1].reset(SkRef(&obj1));
     64         REPORTER_ASSERT(reporter, !obj0.unique());
     65         REPORTER_ASSERT(reporter, !obj1.unique());
     66 
     67         // test out reset with data in the array (and a new allocation)
     68         tmp.reset(0);
     69         REPORTER_ASSERT(reporter, 0 == tmp.count());
     70         REPORTER_ASSERT(reporter, obj0.unique());
     71         REPORTER_ASSERT(reporter, obj1.unique());
     72 
     73         tmp.reset(2);   // this should use the preexisting allocation
     74         REPORTER_ASSERT(reporter, 2 == tmp.count());
     75         tmp[0].reset(SkRef(&obj0));
     76         tmp[1].reset(SkRef(&obj1));
     77     }
     78 
     79     // test out destructor with data in the array (and using existing allocation)
     80     REPORTER_ASSERT(reporter, obj0.unique());
     81     REPORTER_ASSERT(reporter, obj1.unique());
     82 
     83     {
     84         // test out allocating ctor (this should allocate new memory)
     85         SkAutoSTArray<2, sk_sp<RefClass> > tmp(4);
     86         REPORTER_ASSERT(reporter, 4 == tmp.count());
     87 
     88         tmp[0].reset(SkRef(&obj0));
     89         tmp[1].reset(SkRef(&obj1));
     90         REPORTER_ASSERT(reporter, !obj0.unique());
     91         REPORTER_ASSERT(reporter, !obj1.unique());
     92 
     93         // Test out resut with data in the array and malloced storage
     94         tmp.reset(0);
     95         REPORTER_ASSERT(reporter, obj0.unique());
     96         REPORTER_ASSERT(reporter, obj1.unique());
     97 
     98         tmp.reset(2);   // this should use the preexisting storage
     99         tmp[0].reset(SkRef(&obj0));
    100         tmp[1].reset(SkRef(&obj1));
    101         REPORTER_ASSERT(reporter, !obj0.unique());
    102         REPORTER_ASSERT(reporter, !obj1.unique());
    103 
    104         tmp.reset(4);   // this should force a new malloc
    105         REPORTER_ASSERT(reporter, obj0.unique());
    106         REPORTER_ASSERT(reporter, obj1.unique());
    107 
    108         tmp[0].reset(SkRef(&obj0));
    109         tmp[1].reset(SkRef(&obj1));
    110         REPORTER_ASSERT(reporter, !obj0.unique());
    111         REPORTER_ASSERT(reporter, !obj1.unique());
    112     }
    113 
    114     REPORTER_ASSERT(reporter, obj0.unique());
    115     REPORTER_ASSERT(reporter, obj1.unique());
    116 }
    117 
    118 /////////////////////////////////////////////////////////////////////////////
    119 
    120 #define kSEARCH_COUNT   91
    121 
    122 static void test_search(skiatest::Reporter* reporter) {
    123     int         i, array[kSEARCH_COUNT];
    124     SkRandom    rand;
    125 
    126     for (i = 0; i < kSEARCH_COUNT; i++) {
    127         array[i] = rand.nextS();
    128     }
    129 
    130     SkTHeapSort<int>(array, kSEARCH_COUNT);
    131     // make sure we got sorted properly
    132     for (i = 1; i < kSEARCH_COUNT; i++) {
    133         REPORTER_ASSERT(reporter, array[i-1] <= array[i]);
    134     }
    135 
    136     // make sure we can find all of our values
    137     for (i = 0; i < kSEARCH_COUNT; i++) {
    138         int index = SkTSearch<int>(array, kSEARCH_COUNT, array[i], sizeof(int));
    139         REPORTER_ASSERT(reporter, index == i);
    140     }
    141 
    142     // make sure that random values are either found, or the correct
    143     // insertion index is returned
    144     for (i = 0; i < 10000; i++) {
    145         int value = rand.nextS();
    146         int index = SkTSearch<int>(array, kSEARCH_COUNT, value, sizeof(int));
    147 
    148         if (index >= 0) {
    149             REPORTER_ASSERT(reporter,
    150                             index < kSEARCH_COUNT && array[index] == value);
    151         } else {
    152             index = ~index;
    153             REPORTER_ASSERT(reporter, index <= kSEARCH_COUNT);
    154             if (index < kSEARCH_COUNT) {
    155                 REPORTER_ASSERT(reporter, value < array[index]);
    156                 if (index > 0) {
    157                     REPORTER_ASSERT(reporter, value > array[index - 1]);
    158                 }
    159             } else {
    160                 // we should append the new value
    161                 REPORTER_ASSERT(reporter, value > array[kSEARCH_COUNT - 1]);
    162             }
    163         }
    164     }
    165 }
    166 
    167 static void test_utf16(skiatest::Reporter* reporter) {
    168     static const SkUnichar gUni[] = {
    169         0x10000, 0x18080, 0x20202, 0xFFFFF, 0x101234
    170     };
    171 
    172     uint16_t buf[2];
    173 
    174     for (size_t i = 0; i < SK_ARRAY_COUNT(gUni); i++) {
    175         size_t count = SkUTF16_FromUnichar(gUni[i], buf);
    176         REPORTER_ASSERT(reporter, count == 2);
    177         size_t count2 = SkUTF16_CountUnichars(buf, 2 * sizeof(uint16_t));
    178         REPORTER_ASSERT(reporter, count2 == 1);
    179         const uint16_t* ptr = buf;
    180         SkUnichar c = SkUTF16_NextUnichar(&ptr);
    181         REPORTER_ASSERT(reporter, c == gUni[i]);
    182         REPORTER_ASSERT(reporter, ptr - buf == 2);
    183     }
    184 }
    185 
    186 DEF_TEST(Utils, reporter) {
    187     static const struct {
    188         const char* fUtf8;
    189         SkUnichar   fUni;
    190     } gTest[] = {
    191         { "a",                  'a' },
    192         { "\x7f",               0x7f },
    193         { "\xC2\x80",           0x80 },
    194         { "\xC3\x83",           (3 << 6) | 3    },
    195         { "\xDF\xBF",           0x7ff },
    196         { "\xE0\xA0\x80",       0x800 },
    197         { "\xE0\xB0\xB8",       0xC38 },
    198         { "\xE3\x83\x83",       (3 << 12) | (3 << 6) | 3    },
    199         { "\xEF\xBF\xBF",       0xFFFF },
    200         { "\xF0\x90\x80\x80",   0x10000 },
    201         { "\xF3\x83\x83\x83",   (3 << 18) | (3 << 12) | (3 << 6) | 3    }
    202     };
    203 
    204     for (size_t i = 0; i < SK_ARRAY_COUNT(gTest); i++) {
    205         const char* p = gTest[i].fUtf8;
    206         int         n = SkUTF8_CountUnichars(p);
    207         SkUnichar   u0 = SkUTF8_ToUnichar(gTest[i].fUtf8);
    208         SkUnichar   u1 = SkUTF8_NextUnichar(&p);
    209 
    210         REPORTER_ASSERT(reporter, n == 1);
    211         REPORTER_ASSERT(reporter, u0 == u1);
    212         REPORTER_ASSERT(reporter, u0 == gTest[i].fUni);
    213         REPORTER_ASSERT(reporter,
    214                         p - gTest[i].fUtf8 == (int)strlen(gTest[i].fUtf8));
    215     }
    216 
    217     test_utf16(reporter);
    218     test_search(reporter);
    219     test_autounref(reporter);
    220     test_autostarray(reporter);
    221 }
    222 
    223 #define ASCII_BYTE         "X"
    224 #define CONTINUATION_BYTE  "\x80"
    225 #define LEADING_TWO_BYTE   "\xC4"
    226 #define LEADING_THREE_BYTE "\xE0"
    227 #define LEADING_FOUR_BYTE  "\xF0"
    228 #define INVALID_BYTE       "\xFC"
    229 static bool valid_utf8(const char* p, size_t l) {
    230     return SkUTF8_CountUnichars(p, l) >= 0;
    231 }
    232 DEF_TEST(Utils_UTF8_ValidLength, r) {
    233     const char* goodTestcases[] = {
    234         "",
    235         ASCII_BYTE,
    236         ASCII_BYTE ASCII_BYTE,
    237         LEADING_TWO_BYTE CONTINUATION_BYTE,
    238         ASCII_BYTE LEADING_TWO_BYTE CONTINUATION_BYTE,
    239         ASCII_BYTE ASCII_BYTE LEADING_TWO_BYTE CONTINUATION_BYTE,
    240         LEADING_THREE_BYTE CONTINUATION_BYTE CONTINUATION_BYTE,
    241         ASCII_BYTE LEADING_THREE_BYTE CONTINUATION_BYTE CONTINUATION_BYTE,
    242         ASCII_BYTE ASCII_BYTE LEADING_THREE_BYTE CONTINUATION_BYTE CONTINUATION_BYTE,
    243         LEADING_FOUR_BYTE CONTINUATION_BYTE CONTINUATION_BYTE CONTINUATION_BYTE,
    244         ASCII_BYTE LEADING_FOUR_BYTE CONTINUATION_BYTE CONTINUATION_BYTE CONTINUATION_BYTE,
    245         ASCII_BYTE ASCII_BYTE LEADING_FOUR_BYTE CONTINUATION_BYTE CONTINUATION_BYTE
    246             CONTINUATION_BYTE,
    247     };
    248     for (const char* testcase : goodTestcases) {
    249         REPORTER_ASSERT(r, valid_utf8(testcase, strlen(testcase)));
    250     }
    251     const char* badTestcases[] = {
    252         INVALID_BYTE,
    253         INVALID_BYTE CONTINUATION_BYTE,
    254         INVALID_BYTE CONTINUATION_BYTE CONTINUATION_BYTE,
    255         INVALID_BYTE CONTINUATION_BYTE CONTINUATION_BYTE CONTINUATION_BYTE,
    256         LEADING_TWO_BYTE,
    257         CONTINUATION_BYTE,
    258         CONTINUATION_BYTE CONTINUATION_BYTE,
    259         LEADING_THREE_BYTE CONTINUATION_BYTE,
    260         CONTINUATION_BYTE CONTINUATION_BYTE CONTINUATION_BYTE,
    261         LEADING_FOUR_BYTE CONTINUATION_BYTE,
    262         CONTINUATION_BYTE CONTINUATION_BYTE CONTINUATION_BYTE CONTINUATION_BYTE,
    263 
    264         ASCII_BYTE INVALID_BYTE,
    265         ASCII_BYTE INVALID_BYTE CONTINUATION_BYTE,
    266         ASCII_BYTE INVALID_BYTE CONTINUATION_BYTE CONTINUATION_BYTE,
    267         ASCII_BYTE INVALID_BYTE CONTINUATION_BYTE CONTINUATION_BYTE CONTINUATION_BYTE,
    268         ASCII_BYTE LEADING_TWO_BYTE,
    269         ASCII_BYTE CONTINUATION_BYTE,
    270         ASCII_BYTE CONTINUATION_BYTE CONTINUATION_BYTE,
    271         ASCII_BYTE LEADING_THREE_BYTE CONTINUATION_BYTE,
    272         ASCII_BYTE CONTINUATION_BYTE CONTINUATION_BYTE CONTINUATION_BYTE,
    273         ASCII_BYTE LEADING_FOUR_BYTE CONTINUATION_BYTE,
    274         ASCII_BYTE CONTINUATION_BYTE CONTINUATION_BYTE CONTINUATION_BYTE CONTINUATION_BYTE,
    275 
    276         // LEADING_FOUR_BYTE LEADING_TWO_BYTE CONTINUATION_BYTE,
    277     };
    278     for (const char* testcase : badTestcases) {
    279         REPORTER_ASSERT(r, !valid_utf8(testcase, strlen(testcase)));
    280     }
    281 
    282 }
    283