aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/utils/utf8_ut.cpp
blob: 7479acd7a1159c0dc3fc9a003a9595b8f8fe4b47 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include "utf8.h"

#include <library/cpp/testing/unittest/registar.h>

Y_UNIT_TEST_SUITE(TUtf8Tests) {
    Y_UNIT_TEST(Simple) {
        UNIT_ASSERT(NYql::IsUtf8(""));
        UNIT_ASSERT(NYql::IsUtf8("\x01_ASCII_\x7F"));
        UNIT_ASSERT(NYql::IsUtf8("Привет!"));
        UNIT_ASSERT(NYql::IsUtf8("\xF0\x9F\x94\xA2"));

        UNIT_ASSERT(!NYql::IsUtf8("\xf5\x80\x80\x80"));
        UNIT_ASSERT(!NYql::IsUtf8("\xed\xa6\x80"));
        UNIT_ASSERT(!NYql::IsUtf8("\xF0\x9F\x94"));
        UNIT_ASSERT(!NYql::IsUtf8("\xE3\x85\xB6\xE7\x9C\xB0\xE3\x9C\xBA\xE2\xAA\x96\xEE\xA2\x8C\xEC\xAF\xB8\xE1\xB2\xBB\xEC\xA3\x9C\xE3\xAB\x8B\xEC\x95\x92\xE1\x8A\xBF\xE2\x8E\x86\xEC\x9B\x8D\xE2\x8E\xAE\xE3\x8A\xA3\xE0\xAC\xBC\xED\xB6\x85"));
        UNIT_ASSERT(!NYql::IsUtf8("\xc0\xbe\xd0\xb1\xd0\xbd\xd0\xbe\xd0\xb2\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xb8\xd1\x8e"));
    }

    Y_UNIT_TEST(CharSize) {
        UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize(' '), 1);
        UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize('\x00'), 1);
        UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize('\x7F'), 1);
        UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize('\xD1'), 2);
        UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize('\xF0'), 4);
        UNIT_ASSERT_VALUES_EQUAL(NYql::WideCharSize('\xFF'), 0);
    }

    Y_UNIT_TEST(RoundingDown) {
        auto checkDown = [](std::string_view in, std::string_view out) {
            auto res = NYql::RoundToNearestValidUtf8(in, true);
            UNIT_ASSERT(res);
            UNIT_ASSERT(NYql::IsUtf8(*res));
            UNIT_ASSERT_VALUES_EQUAL(*res, out);
            UNIT_ASSERT(*res <= in);
        };
        checkDown("привет", "привет");
        checkDown("тест\x80", "тест\x7f");
        checkDown("привет\xf5", "привет\xf4\x8f\xbf\xbf");
        checkDown("тест2\xee\x80\x7f", "тест2\xed\x9f\xbf");
        checkDown("ага\xf0\xaa\xaa\xff", "ага\xf0\xaa\xaa\xbf");
    }

    Y_UNIT_TEST(RoundingUp) {
        auto checkUp = [](std::string_view in, std::string_view out) {
            auto res = NYql::RoundToNearestValidUtf8(in, false);
            UNIT_ASSERT(res);
            UNIT_ASSERT(NYql::IsUtf8(*res));
            UNIT_ASSERT_VALUES_EQUAL(*res, out);
            UNIT_ASSERT(*res >= in);
        };

        checkUp("", "");
        checkUp("привет", "привет");
        checkUp(\xf6", "б");
        checkUp("\xf4\x8f\xbf\xbfа\xf4\x8f\xbf\xbf\xf5", "\xf4\x8f\xbf\xbfб");
        UNIT_ASSERT(!NYql::RoundToNearestValidUtf8("\xf4\x8f\xbf\xbf\xf5", false));
        UNIT_ASSERT(!NYql::RoundToNearestValidUtf8("\xf5", false));
        checkUp("тест\x80", "тест\xc2\x80");
        checkUp("тест\xdf", "тест\xdf\x80");
        checkUp("тест\xf0\x90\xff", "тест\xf0\x91\x80\x80");
        checkUp("ааа\xff", "ааб");
    }

    Y_UNIT_TEST(NextValid) {
        auto checkNext = [](std::string_view in, std::string_view out) {
            auto res = NYql::NextValidUtf8(in);
            UNIT_ASSERT(res);
            UNIT_ASSERT(NYql::IsUtf8(*res));
            UNIT_ASSERT_VALUES_EQUAL(*res, out);
            UNIT_ASSERT(*res > in);
        };

        UNIT_ASSERT(!NYql::NextValidUtf8(""));
        checkNext("привет", "привеу");
        checkNext("а", "б");
        checkNext(std::string_view("\x00", 1), "\x01");
        checkNext("\xf4\x8f\xbf\xbfа\xf4\x8f\xbf\xbf", "\xf4\x8f\xbf\xbfб");
        UNIT_ASSERT(!NYql::NextValidUtf8("\xf4\x8f\xbf\xbf"));
        UNIT_ASSERT(!NYql::NextValidUtf8("\xf4\x8f\xbf\xbf\xf4\x8f\xbf\xbf"));
    }

    Y_UNIT_TEST(NextValidString) {
        auto checkNext = [](std::string_view in, std::string_view out) {
            auto res = NYql::NextLexicographicString(in);
            UNIT_ASSERT(res);
            UNIT_ASSERT_VALUES_EQUAL(*res, out);
            UNIT_ASSERT(*res > in);
        };

        UNIT_ASSERT(!NYql::NextLexicographicString(""));
        checkNext("привет", "привеу");
        checkNext("а", "б");
        checkNext(std::string_view("\x00", 1), "\x01");
        checkNext("\xf4\x8f\xbf\xbfа\xf4\x8f\xbf\xbf", "\xf4\x8f\xbf\xbfа\xf4\x8f\xbf\xc0");
        UNIT_ASSERT(!NYql::NextLexicographicString("\xff"));
        UNIT_ASSERT(!NYql::NextLexicographicString("\xff\xff"));
        checkNext(std::string_view("x\x00\xff\xff", 4), "x\x01");
    }
}