text_test.cpp revision 275988
1// Copyright (c) 2007 The NetBSD Foundation, Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions
6// are met:
7// 1. Redistributions of source code must retain the above copyright
8//    notice, this list of conditions and the following disclaimer.
9// 2. Redistributions in binary form must reproduce the above copyright
10//    notice, this list of conditions and the following disclaimer in the
11//    documentation and/or other materials provided with the distribution.
12//
13// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26#include "atf-c++/detail/text.hpp"
27
28#include <cstring>
29#include <set>
30#include <vector>
31
32#include <atf-c++.hpp>
33
34// ------------------------------------------------------------------------
35// Test cases for the free functions.
36// ------------------------------------------------------------------------
37
38ATF_TEST_CASE(duplicate);
39ATF_TEST_CASE_HEAD(duplicate)
40{
41    set_md_var("descr", "Tests the duplicate function");
42}
43ATF_TEST_CASE_BODY(duplicate)
44{
45    using atf::text::duplicate;
46
47    const char* orig = "foo";
48
49    char* copy = duplicate(orig);
50    ATF_REQUIRE_EQ(std::strlen(copy), 3);
51    ATF_REQUIRE(std::strcmp(copy, "foo") == 0);
52
53    std::strcpy(copy, "bar");
54    ATF_REQUIRE(std::strcmp(copy, "bar") == 0);
55    ATF_REQUIRE(std::strcmp(orig, "foo") == 0);
56}
57
58ATF_TEST_CASE(join);
59ATF_TEST_CASE_HEAD(join)
60{
61    set_md_var("descr", "Tests the join function");
62}
63ATF_TEST_CASE_BODY(join)
64{
65    using atf::text::join;
66
67    // First set of tests using a non-sorted collection, std::vector.
68    {
69        std::vector< std::string > words;
70        std::string str;
71
72        words.clear();
73        str = join(words, ",");
74        ATF_REQUIRE_EQ(str, "");
75
76        words.clear();
77        words.push_back("");
78        str = join(words, ",");
79        ATF_REQUIRE_EQ(str, "");
80
81        words.clear();
82        words.push_back("");
83        words.push_back("");
84        str = join(words, ",");
85        ATF_REQUIRE_EQ(str, ",");
86
87        words.clear();
88        words.push_back("foo");
89        words.push_back("");
90        words.push_back("baz");
91        str = join(words, ",");
92        ATF_REQUIRE_EQ(str, "foo,,baz");
93
94        words.clear();
95        words.push_back("foo");
96        words.push_back("bar");
97        words.push_back("baz");
98        str = join(words, ",");
99        ATF_REQUIRE_EQ(str, "foo,bar,baz");
100    }
101
102    // Second set of tests using a sorted collection, std::set.
103    {
104        std::set< std::string > words;
105        std::string str;
106
107        words.clear();
108        str = join(words, ",");
109        ATF_REQUIRE_EQ(str, "");
110
111        words.clear();
112        words.insert("");
113        str = join(words, ",");
114        ATF_REQUIRE_EQ(str, "");
115
116        words.clear();
117        words.insert("foo");
118        words.insert("");
119        words.insert("baz");
120        str = join(words, ",");
121        ATF_REQUIRE_EQ(str, ",baz,foo");
122
123        words.clear();
124        words.insert("foo");
125        words.insert("bar");
126        words.insert("baz");
127        str = join(words, ",");
128        ATF_REQUIRE_EQ(str, "bar,baz,foo");
129    }
130}
131
132ATF_TEST_CASE(match);
133ATF_TEST_CASE_HEAD(match)
134{
135    set_md_var("descr", "Tests the match function");
136}
137ATF_TEST_CASE_BODY(match)
138{
139    using atf::text::match;
140
141    ATF_REQUIRE_THROW(std::runtime_error, match("", "["));
142
143    ATF_REQUIRE(match("", ""));
144    ATF_REQUIRE(!match("foo", ""));
145
146    ATF_REQUIRE(match("", ".*"));
147    ATF_REQUIRE(match("", "[a-z]*"));
148
149    ATF_REQUIRE(match("hello", "hello"));
150    ATF_REQUIRE(match("hello", "[a-z]+"));
151    ATF_REQUIRE(match("hello", "^[a-z]+$"));
152
153    ATF_REQUIRE(!match("hello", "helooo"));
154    ATF_REQUIRE(!match("hello", "[a-z]+5"));
155    ATF_REQUIRE(!match("hello", "^ [a-z]+$"));
156}
157
158ATF_TEST_CASE(split);
159ATF_TEST_CASE_HEAD(split)
160{
161    set_md_var("descr", "Tests the split function");
162}
163ATF_TEST_CASE_BODY(split)
164{
165    using atf::text::split;
166
167    std::vector< std::string > words;
168
169    words = split("", " ");
170    ATF_REQUIRE_EQ(words.size(), 0);
171
172    words = split(" ", " ");
173    ATF_REQUIRE_EQ(words.size(), 0);
174
175    words = split("    ", " ");
176    ATF_REQUIRE_EQ(words.size(), 0);
177
178    words = split("a b", " ");
179    ATF_REQUIRE_EQ(words.size(), 2);
180    ATF_REQUIRE_EQ(words[0], "a");
181    ATF_REQUIRE_EQ(words[1], "b");
182
183    words = split("a b c d", " ");
184    ATF_REQUIRE_EQ(words.size(), 4);
185    ATF_REQUIRE_EQ(words[0], "a");
186    ATF_REQUIRE_EQ(words[1], "b");
187    ATF_REQUIRE_EQ(words[2], "c");
188    ATF_REQUIRE_EQ(words[3], "d");
189
190    words = split("foo bar", " ");
191    ATF_REQUIRE_EQ(words.size(), 2);
192    ATF_REQUIRE_EQ(words[0], "foo");
193    ATF_REQUIRE_EQ(words[1], "bar");
194
195    words = split("foo bar baz foobar", " ");
196    ATF_REQUIRE_EQ(words.size(), 4);
197    ATF_REQUIRE_EQ(words[0], "foo");
198    ATF_REQUIRE_EQ(words[1], "bar");
199    ATF_REQUIRE_EQ(words[2], "baz");
200    ATF_REQUIRE_EQ(words[3], "foobar");
201
202    words = split(" foo bar", " ");
203    ATF_REQUIRE_EQ(words.size(), 2);
204    ATF_REQUIRE_EQ(words[0], "foo");
205    ATF_REQUIRE_EQ(words[1], "bar");
206
207    words = split("foo  bar", " ");
208    ATF_REQUIRE_EQ(words.size(), 2);
209    ATF_REQUIRE_EQ(words[0], "foo");
210    ATF_REQUIRE_EQ(words[1], "bar");
211
212    words = split("foo bar ", " ");
213    ATF_REQUIRE_EQ(words.size(), 2);
214    ATF_REQUIRE_EQ(words[0], "foo");
215    ATF_REQUIRE_EQ(words[1], "bar");
216
217    words = split("  foo  bar  ", " ");
218    ATF_REQUIRE_EQ(words.size(), 2);
219    ATF_REQUIRE_EQ(words[0], "foo");
220    ATF_REQUIRE_EQ(words[1], "bar");
221}
222
223ATF_TEST_CASE(split_delims);
224ATF_TEST_CASE_HEAD(split_delims)
225{
226    set_md_var("descr", "Tests the split function using different delimiters");
227}
228ATF_TEST_CASE_BODY(split_delims)
229{
230    using atf::text::split;
231
232    std::vector< std::string > words;
233
234    words = split("", "/");
235    ATF_REQUIRE_EQ(words.size(), 0);
236
237    words = split(" ", "/");
238    ATF_REQUIRE_EQ(words.size(), 1);
239    ATF_REQUIRE_EQ(words[0], " ");
240
241    words = split("    ", "/");
242    ATF_REQUIRE_EQ(words.size(), 1);
243    ATF_REQUIRE_EQ(words[0], "    ");
244
245    words = split("a/b", "/");
246    ATF_REQUIRE_EQ(words.size(), 2);
247    ATF_REQUIRE_EQ(words[0], "a");
248    ATF_REQUIRE_EQ(words[1], "b");
249
250    words = split("aLONGDELIMbcdLONGDELIMef", "LONGDELIM");
251    ATF_REQUIRE_EQ(words.size(), 3);
252    ATF_REQUIRE_EQ(words[0], "a");
253    ATF_REQUIRE_EQ(words[1], "bcd");
254    ATF_REQUIRE_EQ(words[2], "ef");
255}
256
257ATF_TEST_CASE(trim);
258ATF_TEST_CASE_HEAD(trim)
259{
260    set_md_var("descr", "Tests the trim function");
261}
262ATF_TEST_CASE_BODY(trim)
263{
264    using atf::text::trim;
265
266    ATF_REQUIRE_EQ(trim(""), "");
267    ATF_REQUIRE_EQ(trim(" "), "");
268    ATF_REQUIRE_EQ(trim("\t"), "");
269
270    ATF_REQUIRE_EQ(trim(" foo"), "foo");
271    ATF_REQUIRE_EQ(trim("\t foo"), "foo");
272    ATF_REQUIRE_EQ(trim(" \tfoo"), "foo");
273    ATF_REQUIRE_EQ(trim("foo\t "), "foo");
274    ATF_REQUIRE_EQ(trim("foo \t"), "foo");
275
276    ATF_REQUIRE_EQ(trim("foo bar"), "foo bar");
277    ATF_REQUIRE_EQ(trim("\t foo bar"), "foo bar");
278    ATF_REQUIRE_EQ(trim(" \tfoo bar"), "foo bar");
279    ATF_REQUIRE_EQ(trim("foo bar\t "), "foo bar");
280    ATF_REQUIRE_EQ(trim("foo bar \t"), "foo bar");
281}
282
283ATF_TEST_CASE(to_bool);
284ATF_TEST_CASE_HEAD(to_bool)
285{
286    set_md_var("descr", "Tests the to_string function");
287}
288ATF_TEST_CASE_BODY(to_bool)
289{
290    using atf::text::to_bool;
291
292    ATF_REQUIRE(to_bool("true"));
293    ATF_REQUIRE(to_bool("TRUE"));
294    ATF_REQUIRE(to_bool("yes"));
295    ATF_REQUIRE(to_bool("YES"));
296
297    ATF_REQUIRE(!to_bool("false"));
298    ATF_REQUIRE(!to_bool("FALSE"));
299    ATF_REQUIRE(!to_bool("no"));
300    ATF_REQUIRE(!to_bool("NO"));
301
302    ATF_REQUIRE_THROW(std::runtime_error, to_bool(""));
303    ATF_REQUIRE_THROW(std::runtime_error, to_bool("tru"));
304    ATF_REQUIRE_THROW(std::runtime_error, to_bool("true2"));
305    ATF_REQUIRE_THROW(std::runtime_error, to_bool("fals"));
306    ATF_REQUIRE_THROW(std::runtime_error, to_bool("false2"));
307}
308
309ATF_TEST_CASE(to_bytes);
310ATF_TEST_CASE_HEAD(to_bytes)
311{
312    set_md_var("descr", "Tests the to_bytes function");
313}
314ATF_TEST_CASE_BODY(to_bytes)
315{
316    using atf::text::to_bytes;
317
318    ATF_REQUIRE_EQ(0, to_bytes("0"));
319    ATF_REQUIRE_EQ(12345, to_bytes("12345"));
320    ATF_REQUIRE_EQ(2 * 1024, to_bytes("2k"));
321    ATF_REQUIRE_EQ(4 * 1024 * 1024, to_bytes("4m"));
322    ATF_REQUIRE_EQ(int64_t(8) * 1024 * 1024 * 1024, to_bytes("8g"));
323    ATF_REQUIRE_EQ(int64_t(16) * 1024 * 1024 * 1024 * 1024, to_bytes("16t"));
324
325    ATF_REQUIRE_THROW_RE(std::runtime_error, "Empty", to_bytes(""));
326    ATF_REQUIRE_THROW_RE(std::runtime_error, "Unknown size unit 'd'",
327                         to_bytes("12d"));
328    ATF_REQUIRE_THROW(std::runtime_error, to_bytes(" "));
329    ATF_REQUIRE_THROW(std::runtime_error, to_bytes(" k"));
330}
331
332ATF_TEST_CASE(to_string);
333ATF_TEST_CASE_HEAD(to_string)
334{
335    set_md_var("descr", "Tests the to_string function");
336}
337ATF_TEST_CASE_BODY(to_string)
338{
339    using atf::text::to_string;
340
341    ATF_REQUIRE_EQ(to_string('a'), "a");
342    ATF_REQUIRE_EQ(to_string("a"), "a");
343    ATF_REQUIRE_EQ(to_string(5), "5");
344}
345
346ATF_TEST_CASE(to_type);
347ATF_TEST_CASE_HEAD(to_type)
348{
349    set_md_var("descr", "Tests the to_type function");
350}
351ATF_TEST_CASE_BODY(to_type)
352{
353    using atf::text::to_type;
354
355    ATF_REQUIRE_EQ(to_type< int >("0"), 0);
356    ATF_REQUIRE_EQ(to_type< int >("1234"), 1234);
357    ATF_REQUIRE_THROW(std::runtime_error, to_type< int >("   "));
358    ATF_REQUIRE_THROW(std::runtime_error, to_type< int >("0 a"));
359    ATF_REQUIRE_THROW(std::runtime_error, to_type< int >("a"));
360
361    ATF_REQUIRE_EQ(to_type< float >("0.5"), 0.5);
362    ATF_REQUIRE_EQ(to_type< float >("1234.5"), 1234.5);
363    ATF_REQUIRE_THROW(std::runtime_error, to_type< float >("0.5 a"));
364    ATF_REQUIRE_THROW(std::runtime_error, to_type< float >("a"));
365
366    ATF_REQUIRE_EQ(to_type< std::string >("a"), "a");
367}
368
369// ------------------------------------------------------------------------
370// Main.
371// ------------------------------------------------------------------------
372
373ATF_INIT_TEST_CASES(tcs)
374{
375    // Add the test cases for the free functions.
376    ATF_ADD_TEST_CASE(tcs, duplicate);
377    ATF_ADD_TEST_CASE(tcs, join);
378    ATF_ADD_TEST_CASE(tcs, match);
379    ATF_ADD_TEST_CASE(tcs, split);
380    ATF_ADD_TEST_CASE(tcs, split_delims);
381    ATF_ADD_TEST_CASE(tcs, trim);
382    ATF_ADD_TEST_CASE(tcs, to_bool);
383    ATF_ADD_TEST_CASE(tcs, to_bytes);
384    ATF_ADD_TEST_CASE(tcs, to_string);
385    ATF_ADD_TEST_CASE(tcs, to_type);
386}
387