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
|
/*
* Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Array.h>
#include <AK/CharacterTypes.h>
#include <AK/String.h>
#include <AK/Utf8View.h>
#include <LibTest/TestCase.h>
#include <LibUnicode/Emoji.h>
// These emojis are the first subgroup in each Unicode-defined group of emojis, plus some interesting
// hand-picked test cases (such as keycap emoji, which begin with ASCII symbols, and country flags).
static constexpr auto s_smileys_emotion = Array { "๐"sv, "๐"sv, "๐"sv, "๐"sv, "๐"sv, "๐
"sv, "๐คฃ"sv, "๐"sv, "๐"sv, "๐"sv, "๐ซ "sv, "๐"sv, "๐"sv, "๐"sv };
static constexpr auto s_people_body = Array { "๐"sv, "๐ค"sv, "๐๏ธ"sv, "๐"sv, "โ"sv, "๐ซฑ"sv, "๐ซฒ"sv, "๐ซณ"sv, "๐ซด"sv, "๐ซท"sv, "๐ซธ"sv };
static constexpr auto s_animals_nature = Array { "๐ถ"sv, "๐"sv, "๐โ๐ฆบ"sv, "๐ฉ"sv, "๐ฆ"sv, "๐ฆ"sv, "๐ฑ"sv, "๐"sv, "๐โโฌ"sv, "๐ฆ"sv, "๐ฏ"sv, "๐ด"sv, "๐ซ"sv, "๐ซ"sv, "๐"sv, "๐ฆ"sv, "๐ฆ"sv, "๐ฆ"sv, "๐ฆฌ"sv, "๐ฎ"sv, "๐ท"sv, "๐"sv, "๐"sv, "๐ฝ"sv, "๐"sv, "๐ฆ"sv, "๐ฆ"sv, "๐"sv, "๐ญ"sv, "๐"sv, "๐"sv, "๐ฐ"sv, "๐"sv, "๐ฟ๏ธ"sv, "๐ฟ"sv, "๐ฆ"sv, "๐ฆ"sv, "๐ป"sv, "๐ปโโ๏ธ"sv, "๐ปโโ"sv, "๐จ"sv, "๐ผ"sv, "๐ฆฅ"sv, "๐ฆ"sv, "๐ฆก"sv, "๐พ"sv };
static constexpr auto s_food_drink = Array { "๐"sv, "๐"sv, "๐"sv, "๐"sv, "๐"sv, "๐"sv, "๐"sv, "๐ฅญ"sv, "๐"sv, "๐"sv, "๐"sv, "๐"sv, "๐"sv, "๐"sv, "๐ซ"sv, "๐ฅ"sv, "๐
"sv, "๐ซ"sv, "๐ฅฅ"sv };
static constexpr auto s_travel_places = Array { "๐"sv, "๐"sv, "๐"sv, "๐"sv, "๐บ๏ธ"sv, "๐บ"sv, "๐พ"sv, "๐งญ"sv };
static constexpr auto s_activities = Array { "๐"sv, "๐"sv, "๐"sv, "๐"sv, "๐งจ"sv, "โจ"sv, "๐"sv, "๐"sv, "๐"sv, "๐"sv, "๐"sv, "๐"sv, "๐"sv, "๐"sv, "๐"sv, "๐๏ธ"sv, "๐"sv, "๐๏ธ"sv, "๐"sv, "๐ซ"sv };
static constexpr auto s_objects = Array { "๐"sv, "๐ถ๏ธ"sv, "๐ถ"sv, "๐ฆบ"sv, "๐"sv, "๐"sv, "๐งฆ"sv, "๐"sv, "๐ฅป"sv, "๐ฉฑ"sv, "๐ฉฒ"sv, "๐ฉณ"sv, "๐"sv, "๐ชญ"sv, "๐"sv, "๐"sv, "๐๏ธ"sv, "๐"sv, "๐ฉด"sv, "๐ก"sv, "๐ข"sv, "๐ชฎ"sv, "๐"sv, "๐ฉ"sv, "๐"sv, "๐ช"sv, "โ๏ธ"sv, "โ"sv, "๐"sv, "๐"sv, "๐"sv };
static constexpr auto s_symbols = Array { "๐ฎ"sv, "๐ฐ"sv, "โฟ"sv, "๐น"sv, "๐บ"sv, "๐พ"sv, "๐"sv, "๐"sv, "๐"sv, "๐
"sv, "#๏ธโฃ"sv, "#โฃ"sv, "*๏ธโฃ"sv, "*โฃ"sv, "0๏ธโฃ"sv, "0โฃ"sv, "1๏ธโฃ"sv, "1โฃ"sv, "2๏ธโฃ"sv, "2โฃ"sv, "3๏ธโฃ"sv, "3โฃ"sv, "4๏ธโฃ"sv, "4โฃ"sv, "5๏ธโฃ"sv, "5โฃ"sv, "6๏ธโฃ"sv, "6โฃ"sv, "7๏ธโฃ"sv, "7โฃ"sv, "8๏ธโฃ"sv, "8โฃ"sv, "9๏ธโฃ"sv, "9โฃ"sv, "๐"sv };
static constexpr auto s_flags = Array { "๐"sv, "๐ฉ"sv, "๐"sv, "๐ด"sv, "๐ณ๏ธ"sv, "๐ณ"sv, "๐ณ๏ธโ๐"sv, "๐ณโ๐"sv, "๐ณ๏ธโโง๏ธ"sv, "๐ณโโง๏ธ"sv, "๐ณ๏ธโโง"sv, "๐ณโโง"sv, "๐ดโโ ๏ธ"sv, "๐ดโโ "sv, "๐ฆ๐จ"sv, "๐ฆ๐ฉ"sv, "๐ฆ๐ช"sv, "๐ฆ๐ซ"sv, "๐ฆ๐ฌ"sv, "๐ฆ๐ฎ"sv, "๐ฆ๐ฑ"sv, "๐ฆ๐ฒ"sv, "๐ฆ๐ด"sv, "๐ฆ๐ถ"sv, "๐ฆ๐ท"sv, "๐ฆ๐ธ"sv, "๐ฆ๐น"sv, "๐ฆ๐บ"sv, "๐ฆ๐ผ"sv, "๐ฆ๐ฝ"sv, "๐ฆ๐ฟ"sv, "๐ง๐ฆ"sv, "๐ง๐ง"sv, "๐ง๐ฉ"sv, "๐ง๐ช"sv, "๐ง๐ซ"sv, "๐ง๐ฌ"sv, "๐ง๐ญ"sv, "๐ง๐ฎ"sv, "๐ง๐ฏ"sv, "๐ง๐ฑ"sv, "๐ง๐ฒ"sv, "๐ง๐ณ"sv, "๐ง๐ด"sv, "๐ง๐ถ"sv, "๐ง๐ท"sv, "๐ง๐ธ"sv };
TEST_CASE(emoji)
{
auto test_emojis = [](auto const& emojis) {
for (auto emoji : emojis) {
Utf8View view { emoji };
EXPECT(Unicode::could_be_start_of_emoji_sequence(view.begin()));
}
};
test_emojis(s_smileys_emotion);
test_emojis(s_people_body);
test_emojis(s_animals_nature);
test_emojis(s_food_drink);
test_emojis(s_travel_places);
test_emojis(s_activities);
test_emojis(s_objects);
test_emojis(s_symbols);
test_emojis(s_flags);
}
TEST_CASE(emoji_presentation_only)
{
auto test_emoji = [](auto emoji, auto expected_result) {
Utf8View view { emoji };
auto is_start_of_emoji_sequence = Unicode::could_be_start_of_emoji_sequence(view.begin(), Unicode::SequenceType::EmojiPresentation);
EXPECT_EQ(is_start_of_emoji_sequence, expected_result);
};
test_emoji("ยฉ๏ธ"sv, true);
test_emoji("ยฉ"sv, false);
test_emoji("ยฎ๏ธ"sv, true);
test_emoji("ยฎ"sv, false);
test_emoji("\U0001F3F3\u200D\U0001F41E"sv, true); // SerenityOS flag
test_emoji("\U0001F3F3\uFE0F\u200D\U0001F41E"sv, true); // SerenityOS flag
}
TEST_CASE(ascii_is_not_emoji)
{
for (u32 code_point = 0u; is_ascii(code_point); ++code_point) {
auto string = String::from_code_point(code_point);
Utf8View view { string };
EXPECT(!Unicode::could_be_start_of_emoji_sequence(view.begin()));
}
}
|