OILS / cpp / libc_test.cc View on Github | oils.pub

196 lines, 126 significant
1#include "cpp/libc.h"
2
3#include <locale.h> // setlocale()
4#include <regex.h> // regcomp()
5#include <unistd.h> // gethostname()
6
7#include "mycpp/runtime.h"
8#include "vendor/greatest.h"
9
10TEST hostname_test() {
11 BigStr* s0 = libc::gethostname();
12 ASSERT(s0 != nullptr);
13
14 char buf[1024];
15 ASSERT(gethostname(buf, HOST_NAME_MAX) == 0);
16 ASSERT(str_equals(s0, StrFromC(buf)));
17
18 PASS();
19}
20
21TEST realpath_test() {
22 BigStr* result = libc::realpath(StrFromC("/"));
23 ASSERT(str_equals(StrFromC("/"), result));
24
25 bool caught = false;
26 try {
27 libc::realpath(StrFromC("/nonexistent_ZZZ"));
28 } catch (IOError_OSError* e) {
29 caught = true;
30 }
31 ASSERT(caught);
32
33 PASS();
34}
35
36TEST libc_test() {
37 log("sizeof(wchar_t) = %d", sizeof(wchar_t));
38
39 int width = 0;
40
41 // TODO: enable this test. Is it not picking LC_CTYPE?
42 // Do we have to do some initialization like libc.cpython_reset_locale() ?
43#if 0
44 try {
45 // mu character \u{03bc} in utf-8
46 width = libc::wcswidth(StrFromC("\xce\xbc"));
47 } catch (UnicodeError* e) {
48 log("UnicodeError %s", e->message->data_);
49 }
50 ASSERT_EQ_FMT(2, width, "%d");
51#endif
52
53 BigStr* h = libc::gethostname();
54 log("gethostname() = %s %d", h->data_, len(h));
55
56 width = libc::wcswidth(StrFromC("foo"));
57 ASSERT_EQ(3, width);
58
59 libc::print_time(0.1, 0.2, 0.3);
60
61 PASS();
62}
63
64static List<BigStr*>* Groups(BigStr* s, List<int>* indices) {
65 List<BigStr*>* groups = NewList<BigStr*>();
66 int n = len(indices) / 2;
67 for (int i = 0; i < n; ++i) {
68 int start = indices->at(2 * i);
69 int end = indices->at(2 * i + 1);
70 if (start == -1) {
71 groups->append(nullptr);
72 } else {
73 groups->append(s->slice(start, end));
74 }
75 }
76 return groups;
77}
78
79TEST regex_wrapper_test() {
80 BigStr* s1 = StrFromC("-abaacaaa");
81 List<int>* indices = libc::regex_search(StrFromC("(a+).(a+)"), 0, s1, 0);
82 List<BigStr*>* results = Groups(s1, indices);
83 ASSERT_EQ_FMT(3, len(results), "%d");
84 ASSERT(str_equals(StrFromC("abaa"), results->at(0))); // whole match
85 ASSERT(str_equals(StrFromC("a"), results->at(1)));
86 ASSERT(str_equals(StrFromC("aa"), results->at(2)));
87
88 indices = libc::regex_search(StrFromC("z+"), 0, StrFromC("abaacaaa"), 0);
89 ASSERT_EQ(nullptr, indices);
90
91 // Alternation gives unmatched group
92 BigStr* s2 = StrFromC("b");
93 indices = libc::regex_search(StrFromC("(a)|(b)"), 0, s2, 0);
94 results = Groups(s2, indices);
95 ASSERT_EQ_FMT(3, len(results), "%d");
96 ASSERT(str_equals(StrFromC("b"), results->at(0))); // whole match
97 ASSERT_EQ(nullptr, results->at(1));
98 ASSERT(str_equals(StrFromC("b"), results->at(2)));
99
100 // Like Unicode test below
101 indices = libc::regex_search(StrFromC("_._"), 0, StrFromC("_x_"), 0);
102 ASSERT(indices != nullptr);
103 ASSERT_EQ_FMT(2, len(indices), "%d");
104 ASSERT_EQ_FMT(0, indices->at(0), "%d");
105 ASSERT_EQ_FMT(3, indices->at(1), "%d");
106
107 // TODO(unicode)
108#if 0
109 //indices = libc::regex_search(StrFromC("_._"), 0, StrFromC("_\u03bc_"), 0);
110 indices = libc::regex_search(StrFromC("_._"), 0, StrFromC("_μ_"), 0);
111 ASSERT(indices != nullptr);
112 ASSERT_EQ_FMT(2, len(indices), "%d");
113 ASSERT_EQ_FMT(0, indices->at(0), "%d");
114 ASSERT_EQ_FMT(0, indices->at(0), "%d");
115#endif
116
117 Tuple2<int, int>* result;
118 BigStr* s = StrFromC("oXooXoooXoX");
119 result = libc::regex_first_group_match(StrFromC("(X.)"), s, 0);
120 ASSERT_EQ_FMT(1, result->at0(), "%d");
121 ASSERT_EQ_FMT(3, result->at1(), "%d");
122
123 result = libc::regex_first_group_match(StrFromC("(X.)"), s, 3);
124 ASSERT_EQ_FMT(4, result->at0(), "%d");
125 ASSERT_EQ_FMT(6, result->at1(), "%d");
126
127 result = libc::regex_first_group_match(StrFromC("(X.)"), s, 6);
128 ASSERT_EQ_FMT(8, result->at0(), "%d");
129 ASSERT_EQ_FMT(10, result->at1(), "%d");
130
131 PASS();
132}
133
134TEST glob_test() {
135 // This depends on the file system
136 auto files = libc::glob(StrFromC("*.testdata"));
137 // 3 files are made by the shell wrapper
138 ASSERT_EQ_FMT(3, len(files), "%d");
139
140 print(files->at(0));
141
142 auto files2 = libc::glob(StrFromC("*.pyzzz"));
143 ASSERT_EQ_FMT(0, len(files2), "%d");
144
145 PASS();
146}
147
148TEST fnmatch_test() {
149 BigStr* s1 = (StrFromC("foo.py "))->strip();
150 ASSERT(libc::fnmatch(StrFromC("*.py"), s1));
151 ASSERT(!libc::fnmatch(StrFromC("*.py"), StrFromC("foo.p")));
152
153 // Unicode - ? is byte or code point?
154 ASSERT(libc::fnmatch(StrFromC("_?_"), StrFromC("_x_")));
155
156 // TODO(unicode)
157 // ASSERT(libc::fnmatch(StrFromC("_?_"), StrFromC("_\u03bc_")));
158 // ASSERT(libc::fnmatch(StrFromC("_?_"), StrFromC("_μ_")));
159
160 // extended glob
161 ASSERT(libc::fnmatch(StrFromC("*(foo|bar).py"), StrFromC("foo.py")));
162 ASSERT(!libc::fnmatch(StrFromC("*(foo|bar).py"), StrFromC("foo.p")));
163
164 PASS();
165}
166
167TEST for_test_coverage() {
168 // Sometimes we're not connected to a terminal
169 try {
170 libc::get_terminal_width();
171 } catch (IOError_OSError* e) {
172 }
173
174 PASS();
175}
176
177GREATEST_MAIN_DEFS();
178
179int main(int argc, char** argv) {
180 gHeap.Init();
181
182 GREATEST_MAIN_BEGIN();
183
184 RUN_TEST(hostname_test);
185 RUN_TEST(realpath_test);
186 RUN_TEST(libc_test);
187 RUN_TEST(regex_wrapper_test);
188 RUN_TEST(glob_test);
189 RUN_TEST(fnmatch_test);
190 RUN_TEST(for_test_coverage);
191
192 gHeap.CleanProcessExit();
193
194 GREATEST_MAIN_END();
195 return 0;
196}