FTXUI 7.0.3
C++ functional terminal UI.
Loading...
Searching...
No Matches
component_fuzzer.cpp
Go to the documentation of this file.
1// Copyright 2021 Arthur Sonzogni. All rights reserved.
2// Use of this source code is governed by the MIT license that can be found in
3// the LICENSE file.
4#include <cassert>
7#include <vector>
10
11using namespace ftxui;
12namespace {
13
14bool GeneratorBool(const char*& data, size_t& size) {
15 if (size == 0) {
16 return false;
17 }
18
19 auto out = bool(data[0] % 2);
20 data++;
21 size--;
22 return out;
23}
24
25std::string GeneratorString(const char*& data, size_t& size) {
26 int index = 0;
27 while (index < size && data[index]) {
28 ++index;
29 }
30
31 auto out = std::string(data, data + index);
32 data += index;
33 size -= index;
34
35 // The input component do not support invalid UTF8 yet.
36 try {
37 to_wstring(out);
38 } catch (...) {
39 return "0";
40 }
41 return std::move(out);
42}
43
44int GeneratorInt(const char* data, size_t size) {
45 if (size == 0) {
46 return 0;
47 }
48 auto out = int(data[0]);
49 data++;
50 size--;
51 return out;
52}
53
54Color GeneratorColor(const char* data, size_t size) {
55 return Color::RGB(GeneratorInt(data, size), GeneratorInt(data, size),
56 GeneratorInt(data, size));
57}
58
59AnimatedColorOption GeneratorAnimatedColorOption(const char* data,
60 size_t size) {
61 AnimatedColorOption option;
62 option.enabled = GeneratorBool(data, size);
63 option.inactive = GeneratorColor(data, size);
64 option.active = GeneratorColor(data, size);
65 option.duration = std::chrono::milliseconds(GeneratorInt(data, size));
66 return option;
67}
68
69AnimatedColorsOption GeneratorAnimatedColorsOptions(const char* data,
70 size_t size) {
71 AnimatedColorsOption option;
72 option.background = GeneratorAnimatedColorOption(data, size);
73 option.foreground = GeneratorAnimatedColorOption(data, size);
74 return option;
75}
76
77ButtonOption GeneratorButtonOption(const char* data, size_t size) {
78 ButtonOption option;
79 option.animated_colors = GeneratorAnimatedColorsOptions(data, size);
80 return option;
81}
82
83UnderlineOption GeneratorUnderlineOption(const char* data, size_t size) {
84 UnderlineOption option;
85 option.enabled = GeneratorBool(data, size);
86 option.color_active = GeneratorColor(data, size);
87 option.color_inactive = GeneratorColor(data, size);
88 option.leader_duration = std::chrono::milliseconds(GeneratorInt(data, size));
89 option.follower_duration =
90 std::chrono::milliseconds(GeneratorInt(data, size));
91 option.leader_delay = std::chrono::milliseconds(GeneratorInt(data, size));
92 option.follower_delay = std::chrono::milliseconds(GeneratorInt(data, size));
93 return option;
94}
95
96MenuEntryOption GeneratorMenuEntryOption(const char* data, size_t size) {
97 MenuEntryOption option;
98 option.animated_colors = GeneratorAnimatedColorsOptions(data, size);
99 return option;
100}
101
102MenuOption GeneratorMenuOption(const char* data, size_t size) {
103 MenuOption option;
104 option.underline = GeneratorUnderlineOption(data, size);
105 option.entries_option = GeneratorMenuEntryOption(data, size);
106 option.direction = static_cast<Direction>(GeneratorInt(data, size) % 4);
107 return option;
108}
109
110bool g_bool;
111int g_int;
112std::vector<std::string> g_list;
113
114Components GeneratorComponents(const char*& data, size_t& size, int depth);
115
116Component GeneratorComponent(const char*& data, size_t& size, int depth) {
117 depth--;
118 int value = GeneratorInt(data, size);
119 if (depth <= 0) {
120 return Button(GeneratorString(data, size), [] {});
121 }
122
123 constexpr int value_max = 26;
124 value = (value % value_max + value_max) % value_max;
125 switch (value) {
126 case 0:
127 return Button(
128 GeneratorString(data, size), [] {},
129 GeneratorButtonOption(data, size));
130 case 1:
131 return Checkbox(GeneratorString(data, size), &g_bool);
132 case 2:
133 return Input(GeneratorString(data, size), GeneratorString(data, size));
134 case 3:
135 return Menu(&g_list, &g_int, GeneratorMenuOption(data, size));
136 case 4:
137 return Radiobox(&g_list, &g_int);
138 case 5:
139 return Toggle(&g_list, &g_int);
140 case 6:
141 return Slider(GeneratorString(data, size), &g_int,
142 GeneratorInt(data, size), GeneratorInt(data, size),
143 GeneratorInt(data, size));
144 case 7:
145 return ResizableSplitLeft(GeneratorComponent(data, size, depth - 1),
146 GeneratorComponent(data, size, depth - 1),
147 &g_int);
148 case 8:
149 return ResizableSplitRight(GeneratorComponent(data, size, depth - 1),
150 GeneratorComponent(data, size, depth - 1),
151 &g_int);
152 case 9:
153 return ResizableSplitTop(GeneratorComponent(data, size, depth - 1),
154 GeneratorComponent(data, size, depth - 1),
155 &g_int);
156 case 10:
157 return ResizableSplitBottom(GeneratorComponent(data, size, depth - 1),
158 GeneratorComponent(data, size, depth - 1),
159 &g_int);
160 case 11:
161 return Container::Vertical(GeneratorComponents(data, size, depth - 1));
162
163 case 12:
164 return Container::Vertical(GeneratorComponents(data, size, depth - 1),
165 &g_int);
166
167 case 13:
168 return Container::Horizontal(GeneratorComponents(data, size, depth - 1));
169 case 14:
170 return Container::Horizontal(GeneratorComponents(data, size, depth - 1),
171 &g_int);
172 case 15:
173 return Container::Tab(GeneratorComponents(data, size, depth - 1), &g_int);
174 case 16:
175 return Maybe(GeneratorComponent(data, size, depth - 1), &g_bool);
176 case 17:
177 return Dropdown(&g_list, &g_int);
178 case 18:
179 return Collapsible(GeneratorString(data, size),
180 GeneratorComponent(data, size, depth - 1),
181 GeneratorBool(data, size));
182 case 19:
183 return Container::Stacked(GeneratorComponents(data, size, depth - 1));
184 case 20:
185 return MenuEntry(GeneratorString(data, size));
186 case 21:
187 return Renderer(GeneratorComponent(data, size, depth - 1),
188 [] { return text("hello"); });
189 case 22:
190 return CatchEvent(GeneratorComponent(data, size, depth - 1),
191 [](Event) { return true; });
192 case 23:
193 return Modal(GeneratorComponent(data, size, depth - 1),
194 GeneratorComponent(data, size, depth - 1), &g_bool);
195 case 24:
196 return Hoverable(GeneratorComponent(data, size, depth - 1), &g_bool);
197 case 25: {
198 WindowOptions options;
199 options.inner = GeneratorComponent(data, size, depth - 1);
200 options.title = GeneratorString(data, size);
201 return Window(options);
202 }
203 default:
204 assert(false);
205 }
206}
207
208Components GeneratorComponents(const char*& data, size_t& size, int depth) {
209 Components out;
210 if (depth > 0) {
211 while (size && GeneratorInt(data, size) % 2) {
212 out.push_back(GeneratorComponent(data, size, depth - 1));
213 }
214 }
215 return std::move(out);
216}
217
218} // namespace
219extern "C" int LLVMFuzzerTestOneInput(const char* data, size_t size) {
220 g_bool = GeneratorBool(data, size);
221 g_int = GeneratorInt(data, size);
222 g_list = {
223 "test_1", "test_2", "test_3", "test_4", "test_5",
224 };
225
226 int depth = 10;
227 auto component = GeneratorComponent(data, size, depth);
228
229 int width = GeneratorInt(data, size);
230 int height = GeneratorInt(data, size);
231
232 width %= 500;
233 width += 500;
234
235 height %= 500;
236 height += 500;
237
238 auto screen =
239 Screen::Create(Dimension::Fixed(width), Dimension::Fixed(height));
240
241 // Generate some events.
242 std::vector<Event> events;
243 auto parser =
244 TerminalInputParser([&](const Event& event) { events.push_back(event); });
245
246 for (size_t i = 0; i < size; ++i) {
247 parser.Add(data[i]);
248 }
249
250 for (const auto& event : events) {
251 component->OnEvent(event);
252 auto document = component->Render();
253 Render(screen, document);
254 }
255 return 0; // Non-zero return values are reserved for future use.
256}
int LLVMFuzzerTestOneInput(const char *data, size_t size)
Component Button(ConstStringRef label, std::function< void()> on_click, ButtonOption options=ButtonOption::Simple())
Dessine un bouton. Exécute une fonction lorsqu'il est cliqué.
Component ResizableSplitTop(Component main, Component back, int *main_size)
Une division verticale entre deux composants, configurable en utilisant la souris.
Component Toggle(ConstStringListRef entries, int *selected)
Une liste horizontale d'éléments. L'utilisateur peut naviguer à travers eux.
FTXUI_EXPORT(COMPONENT) ComponentDecorator Maybe(std Component Modal(Component main, Component modal, const bool *show_modal)
Definition modal.cpp:18
Component Renderer(Component child, std::function< Element()>)
Retourne un nouveau Component, similaire à |child|, mais utilisant |render| comme événement Component...
Component Hoverable(Component component, bool *hover)
Encapsule un composant. Donne la possibilité de savoir s'il est survolé par la souris.
Definition hoverable.cpp:33
Component Checkbox(ConstStringRef label, bool *checked, CheckboxOption options=CheckboxOption::Simple())
Dessine un élément cochable.
Component Maybe(Component child, std::function< bool()> show)
Décore un composant |child|. Il est affiché uniquement lorsque |show| retourne vrai.
Component ResizableSplitRight(Component main, Component back, int *main_size)
Une division horizontale entre deux composants, configurable en utilisant la souris.
Component Input(StringRef content, InputOption options={})
Une boîte de saisie pour éditer du texte.
Component Dropdown(ConstStringListRef entries, int *selected)
Un menu déroulant.
Component Radiobox(ConstStringListRef entries, int *selected_, RadioboxOption options={})
Une liste d'éléments, où un seul peut être sélectionné.
Component ResizableSplitBottom(Component main, Component back, int *main_size)
Une division verticale entre deux composants, configurable en utilisant la souris.
Component Menu(ConstStringListRef entries, int *selected_, MenuOption options=MenuOption::Vertical())
Une liste de texte. L'élément focalisé est sélectionné.
Component ResizableSplitLeft(Component main, Component back, int *main_size)
Une division horizontale entre deux composants, configurable en utilisant la souris.
Component MenuEntry(ConstStringRef label, MenuEntryOption options={})
Une entrée de menu spécifique. Elles peuvent être placées dans un Container::Vertical pour former un ...
Element text(std::string_view text)
Affiche un morceau de texte unicode encodé en UTF8.
Decorator size(WidthOrHeight direction, Constraint constraint, int value)
Applique une contrainte sur la taille d'un élément.
Direction
Direction est une énumération qui représente les quatre directions cardinales.
Definition direction.hpp:15
Component Window(std::string title, Component component)
L'espace de noms FTXUI ftxui::
Definition animation.hpp:11
std::vector< Component > Components
Component Collapsible(ConstStringRef label, Component child, Ref< bool > show=false)
Un composant repliable. Il affiche une case à cocher avec une flèche. Une fois activé,...
Component Slider(SliderOption< T > options)
Un curseur dans n'importe quelle direction.
FTXUI_EXPORT(SCREEN) std FTXUI_EXPORT(SCREEN) std std::wstring to_wstring(T s)
Definition string.hpp:18
void Render(Screen &screen, Node *node, Selection &selection)
Definition node.cpp:105
int value
Definition elements.hpp:195
std::shared_ptr< ComponentBase > Component
Definition app.hpp:23
Component CatchEvent(Component child, std::function< bool(Event)>)