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 
     10 #include <stdarg.h>
     11 #include <stdio.h>
     12 #include <thread>
     13 
     14 #include "SkString.h"
     15 #include "SkStringUtils.h"
     16 
     17 DEF_TEST(String, reporter) {
     18     SkString    a;
     19     SkString    b((size_t)0);
     20     SkString    c("");
     21     SkString    d(nullptr, 0);
     22 
     23     REPORTER_ASSERT(reporter, a.isEmpty());
     24     REPORTER_ASSERT(reporter, a == b && a == c && a == d);
     25 
     26     a.set("hello");
     27     b.set("hellox", 5);
     28     c.set(a);
     29     d.resize(5);
     30     memcpy(d.writable_str(), "helloz", 5);
     31 
     32     REPORTER_ASSERT(reporter, !a.isEmpty());
     33     REPORTER_ASSERT(reporter, a.size() == 5);
     34     REPORTER_ASSERT(reporter, a == b && a == c && a == d);
     35     REPORTER_ASSERT(reporter, a.equals("hello", 5));
     36     REPORTER_ASSERT(reporter, a.equals("hello"));
     37     REPORTER_ASSERT(reporter, !a.equals("help"));
     38 
     39     REPORTER_ASSERT(reporter,  a.startsWith("hell"));
     40     REPORTER_ASSERT(reporter,  a.startsWith('h'));
     41     REPORTER_ASSERT(reporter, !a.startsWith( "ell"));
     42     REPORTER_ASSERT(reporter, !a.startsWith( 'e'));
     43     REPORTER_ASSERT(reporter,  a.startsWith(""));
     44     REPORTER_ASSERT(reporter,  a.endsWith("llo"));
     45     REPORTER_ASSERT(reporter,  a.endsWith('o'));
     46     REPORTER_ASSERT(reporter, !a.endsWith("ll" ));
     47     REPORTER_ASSERT(reporter, !a.endsWith('l'));
     48     REPORTER_ASSERT(reporter,  a.endsWith(""));
     49     REPORTER_ASSERT(reporter,  a.contains("he"));
     50     REPORTER_ASSERT(reporter,  a.contains("ll"));
     51     REPORTER_ASSERT(reporter,  a.contains("lo"));
     52     REPORTER_ASSERT(reporter,  a.contains("hello"));
     53     REPORTER_ASSERT(reporter, !a.contains("hellohello"));
     54     REPORTER_ASSERT(reporter,  a.contains(""));
     55     REPORTER_ASSERT(reporter,  a.contains('e'));
     56     REPORTER_ASSERT(reporter, !a.contains('z'));
     57 
     58     SkString    e(a);
     59     SkString    f("hello");
     60     SkString    g("helloz", 5);
     61 
     62     REPORTER_ASSERT(reporter, a == e && a == f && a == g);
     63 
     64     b.set("world");
     65     c = b;
     66     REPORTER_ASSERT(reporter, a != b && a != c && b == c);
     67 
     68     a.append(" world");
     69     e.append("worldz", 5);
     70     e.insert(5, " ");
     71     f.set("world");
     72     f.prepend("hello ");
     73     REPORTER_ASSERT(reporter, a.equals("hello world") && a == e && a == f);
     74 
     75     a.reset();
     76     b.resize(0);
     77     REPORTER_ASSERT(reporter, a.isEmpty() && b.isEmpty() && a == b);
     78 
     79     a.set("a");
     80     a.set("ab");
     81     a.set("abc");
     82     a.set("abcd");
     83 
     84     a.set("");
     85     a.appendS32(0x7FFFFFFFL);
     86     REPORTER_ASSERT(reporter, a.equals("2147483647"));
     87     a.set("");
     88     a.appendS32(0x80000001L);
     89     REPORTER_ASSERT(reporter, a.equals("-2147483647"));
     90     a.set("");
     91     a.appendS32(0x80000000L);
     92     REPORTER_ASSERT(reporter, a.equals("-2147483648"));
     93 
     94     a.set("");
     95     a.appendU32(0x7FFFFFFFUL);
     96     REPORTER_ASSERT(reporter, a.equals("2147483647"));
     97     a.set("");
     98     a.appendU32(0x80000001UL);
     99     REPORTER_ASSERT(reporter, a.equals("2147483649"));
    100     a.set("");
    101     a.appendU32(0xFFFFFFFFUL);
    102     REPORTER_ASSERT(reporter, a.equals("4294967295"));
    103 
    104     a.set("");
    105     a.appendS64(0x7FFFFFFFFFFFFFFFLL, 0);
    106     REPORTER_ASSERT(reporter, a.equals("9223372036854775807"));
    107     a.set("");
    108     a.appendS64(0x8000000000000001LL, 0);
    109     REPORTER_ASSERT(reporter, a.equals("-9223372036854775807"));
    110     a.set("");
    111     a.appendS64(0x8000000000000000LL, 0);
    112     REPORTER_ASSERT(reporter, a.equals("-9223372036854775808"));
    113     a.set("");
    114     a.appendS64(0x0000000001000000LL, 15);
    115     REPORTER_ASSERT(reporter, a.equals("000000016777216"));
    116     a.set("");
    117     a.appendS64(0xFFFFFFFFFF000000LL, 15);
    118     REPORTER_ASSERT(reporter, a.equals("-000000016777216"));
    119 
    120     a.set("");
    121     a.appendU64(0x7FFFFFFFFFFFFFFFULL, 0);
    122     REPORTER_ASSERT(reporter, a.equals("9223372036854775807"));
    123     a.set("");
    124     a.appendU64(0x8000000000000001ULL, 0);
    125     REPORTER_ASSERT(reporter, a.equals("9223372036854775809"));
    126     a.set("");
    127     a.appendU64(0xFFFFFFFFFFFFFFFFULL, 0);
    128     REPORTER_ASSERT(reporter, a.equals("18446744073709551615"));
    129     a.set("");
    130     a.appendU64(0x0000000001000000ULL, 15);
    131     REPORTER_ASSERT(reporter, a.equals("000000016777216"));
    132 
    133     a.printf("%i", 0);
    134     REPORTER_ASSERT(reporter, a.equals("0"));
    135     a.printf("%g", 3.14);
    136     REPORTER_ASSERT(reporter, a.equals("3.14"));
    137     a.printf("hello %s", "skia");
    138     REPORTER_ASSERT(reporter, a.equals("hello skia"));
    139 
    140     static const struct {
    141         SkScalar    fValue;
    142         const char* fString;
    143     } gRec[] = {
    144         { 0,            "0" },
    145         { SK_Scalar1,   "1" },
    146         { -SK_Scalar1,  "-1" },
    147         { SK_Scalar1/2, "0.5" },
    148   #if defined(SK_BUILD_FOR_WIN) && (_MSC_VER < 1900)
    149         { 3.4028234e38f,   "3.4028235e+038" },
    150         { -3.4028234e38f, "-3.4028235e+038" },
    151   #else
    152         { 3.4028234e38f,   "3.4028235e+38" },
    153         { -3.4028234e38f, "-3.4028235e+38" },
    154   #endif
    155     };
    156     for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) {
    157         a.reset();
    158         a.appendScalar(gRec[i].fValue);
    159         REPORTER_ASSERT(reporter, a.size() <= SkStrAppendScalar_MaxSize);
    160         if (!a.equals(gRec[i].fString)) {
    161             ERRORF(reporter, "received <%s> expected <%s>\n", a.c_str(), gRec[i].fString);
    162         }
    163     }
    164 
    165     REPORTER_ASSERT(reporter, SkStringPrintf("%i", 0).equals("0"));
    166 
    167     char buffer [40];
    168     memset(buffer, 'a', 40);
    169     REPORTER_ASSERT(reporter, buffer[18] == 'a');
    170     REPORTER_ASSERT(reporter, buffer[19] == 'a');
    171     REPORTER_ASSERT(reporter, buffer[20] == 'a');
    172     snprintf(buffer, 20, "%30d", 0);
    173     REPORTER_ASSERT(reporter, buffer[18] == ' ');
    174     REPORTER_ASSERT(reporter, buffer[19] == 0);
    175     REPORTER_ASSERT(reporter, buffer[20] == 'a');
    176 
    177     REPORTER_ASSERT(reporter, SkStringPrintf("%i", 0).equals("0"));
    178 
    179     // 2000 is larger than the static buffer size inside SkString.cpp
    180     a = SkStringPrintf("%2000s", " ");
    181     REPORTER_ASSERT(reporter, a.size() == 2000);
    182     for (size_t i = 0; i < a.size(); ++i) {
    183         if (a[i] != ' ') {
    184             ERRORF(reporter, "SkStringPrintf fail: a[%d] = '%c'", i, a[i]);
    185             break;
    186         }
    187     }
    188     a.reset();
    189     a.printf("%2000s", " ");
    190     REPORTER_ASSERT(reporter, a.size() == 2000);
    191     for (size_t i = 0; i < a.size(); ++i) {
    192         if (a[i] != ' ') {
    193             ERRORF(reporter, "SkStringPrintf fail: a[%d] = '%c'", i, a[i]);
    194             break;
    195         }
    196     }
    197 }
    198 
    199 DEF_TEST(String_SkStrSplit, r) {
    200     SkTArray<SkString> results;
    201 
    202     SkStrSplit("a-_b_c-dee--f-_-_-g-", "-_", &results);
    203     REPORTER_ASSERT(r, results.count() == 6);
    204     REPORTER_ASSERT(r, results[0].equals("a"));
    205     REPORTER_ASSERT(r, results[1].equals("b"));
    206     REPORTER_ASSERT(r, results[2].equals("c"));
    207     REPORTER_ASSERT(r, results[3].equals("dee"));
    208     REPORTER_ASSERT(r, results[4].equals("f"));
    209     REPORTER_ASSERT(r, results[5].equals("g"));
    210 
    211     results.reset();
    212     SkStrSplit("\n", "\n", &results);
    213     REPORTER_ASSERT(r, results.count() == 0);
    214 
    215     results.reset();
    216     SkStrSplit("", "\n", &results);
    217     REPORTER_ASSERT(r, results.count() == 0);
    218 
    219     results.reset();
    220     SkStrSplit("a", "\n", &results);
    221     REPORTER_ASSERT(r, results.count() == 1);
    222     REPORTER_ASSERT(r, results[0].equals("a"));
    223 }
    224 DEF_TEST(String_SkStrSplit_All, r) {
    225     SkTArray<SkString> results;
    226     SkStrSplit("a-_b_c-dee--f-_-_-g-", "-_", kStrict_SkStrSplitMode, &results);
    227     REPORTER_ASSERT(r, results.count() == 13);
    228     REPORTER_ASSERT(r, results[0].equals("a"));
    229     REPORTER_ASSERT(r, results[1].equals(""));
    230     REPORTER_ASSERT(r, results[2].equals("b"));
    231     REPORTER_ASSERT(r, results[3].equals("c"));
    232     REPORTER_ASSERT(r, results[4].equals("dee"));
    233     REPORTER_ASSERT(r, results[5].equals(""));
    234     REPORTER_ASSERT(r, results[6].equals("f"));
    235     REPORTER_ASSERT(r, results[7].equals(""));
    236     REPORTER_ASSERT(r, results[8].equals(""));
    237     REPORTER_ASSERT(r, results[9].equals(""));
    238     REPORTER_ASSERT(r, results[10].equals(""));
    239     REPORTER_ASSERT(r, results[11].equals("g"));
    240     REPORTER_ASSERT(r, results[12].equals(""));
    241 
    242     results.reset();
    243     SkStrSplit("\n", "\n", kStrict_SkStrSplitMode, &results);
    244     REPORTER_ASSERT(r, results.count() == 2);
    245     REPORTER_ASSERT(r, results[0].equals(""));
    246     REPORTER_ASSERT(r, results[1].equals(""));
    247 
    248     results.reset();
    249     SkStrSplit("", "\n", kStrict_SkStrSplitMode, &results);
    250     REPORTER_ASSERT(r, results.count() == 0);
    251 
    252     results.reset();
    253     SkStrSplit("a", "\n", kStrict_SkStrSplitMode, &results);
    254     REPORTER_ASSERT(r, results.count() == 1);
    255     REPORTER_ASSERT(r, results[0].equals("a"));
    256 
    257     results.reset();
    258     SkStrSplit(",,", ",", kStrict_SkStrSplitMode, &results);
    259     REPORTER_ASSERT(r, results.count() == 3);
    260     REPORTER_ASSERT(r, results[0].equals(""));
    261     REPORTER_ASSERT(r, results[1].equals(""));
    262     REPORTER_ASSERT(r, results[2].equals(""));
    263 
    264     results.reset();
    265     SkStrSplit(",a,b,", ",", kStrict_SkStrSplitMode, &results);
    266     REPORTER_ASSERT(r, results.count() == 4);
    267     REPORTER_ASSERT(r, results[0].equals(""));
    268     REPORTER_ASSERT(r, results[1].equals("a"));
    269     REPORTER_ASSERT(r, results[2].equals("b"));
    270     REPORTER_ASSERT(r, results[3].equals(""));
    271 }
    272 
    273 // https://bugs.chromium.org/p/skia/issues/detail?id=7107
    274 DEF_TEST(String_Threaded, r) {
    275     SkString str("foo");
    276 
    277     std::thread threads[5];
    278     for (auto& thread : threads) {
    279         thread = std::thread([&] {
    280             SkString copy = str;
    281             (void)copy.equals("test");
    282         });
    283     }
    284     for (auto& thread : threads) {
    285         thread.join();
    286     }
    287 }
    288 
    289 // Ensure that the string allocate doesn't internally overflow any calculations, and accidentally
    290 // let us create a string with a requested length longer than we can manage.
    291 DEF_TEST(String_huge, r) {
    292     // start testing slightly below max 32
    293     size_t size = SK_MaxU32 - 16;
    294     // See where we crash, and manually check that its at the right point.
    295     //
    296     //  To test, change the false to true
    297     while (false) {
    298         // On a 64bit build, this should crash when size == 1 << 32, since we can't store
    299         // that length in the string's header (which has a u32 slot for the length).
    300         //
    301         // On a 32bit build, this should crash the first time around, since we can't allocate
    302         // anywhere near this amount.
    303         //
    304         SkString str(size);
    305         size += 1;
    306     }
    307 }
    308 
    309 DEF_TEST(String_fromUTF16, r) {
    310     // test data produced with `iconv`.
    311     const uint16_t test1[] = {
    312         0xD835, 0xDCD0, 0xD835, 0xDCD1, 0xD835, 0xDCD2, 0xD835, 0xDCD3, 0xD835, 0xDCD4, 0x0020,
    313         0xD835, 0xDCD5, 0xD835, 0xDCD6, 0xD835, 0xDCD7, 0xD835, 0xDCD8, 0xD835, 0xDCD9
    314     };
    315     REPORTER_ASSERT(r, SkStringFromUTF16(test1, SK_ARRAY_COUNT(test1)).equals(" "));
    316 
    317     const uint16_t test2[] = {
    318         0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0020, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A,
    319     };
    320     REPORTER_ASSERT(r, SkStringFromUTF16(test2, SK_ARRAY_COUNT(test2)).equals("ABCDE FGHIJ"));
    321 
    322     const uint16_t test3[] = {
    323         0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x0020, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA,
    324     };
    325     REPORTER_ASSERT(r, SkStringFromUTF16(test3, SK_ARRAY_COUNT(test3)).equals(" "));
    326 }
    327 
    328