1 // Copyright (c) 2018, ETH Zurich and UNC Chapel Hill.
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 are met:
6 //
7 //     * Redistributions of source code must retain the above copyright
8 //       notice, this list of conditions and the following disclaimer.
9 //
10 //     * Redistributions in binary form must reproduce the above copyright
11 //       notice, this list of conditions and the following disclaimer in the
12 //       documentation and/or other materials provided with the distribution.
13 //
14 //     * Neither the name of ETH Zurich and UNC Chapel Hill nor the names of
15 //       its contributors may be used to endorse or promote products derived
16 //       from this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 // POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Author: Johannes L. Schoenberger (jsch-at-demuc-dot-de)
31 
32 #define TEST_NAME "util/string"
33 #include "util/testing.h"
34 
35 #include "util/string.h"
36 
37 using namespace colmap;
38 
39 #define TEST_STRING_INPLACE(Func, str, ref_str) \
40   {                                             \
41     std::string str_inplace = str;              \
42     Func(&str_inplace);                         \
43     BOOST_CHECK_EQUAL(str_inplace, ref_str);    \
44   }
45 
BOOST_AUTO_TEST_CASE(TestStringPrintf)46 BOOST_AUTO_TEST_CASE(TestStringPrintf) {
47   BOOST_CHECK_EQUAL(StringPrintf("%s", "test"), "test");
48   BOOST_CHECK_EQUAL(StringPrintf("%d", 1), "1");
49   BOOST_CHECK_EQUAL(StringPrintf("%.3f", 1.234), "1.234");
50   BOOST_CHECK_EQUAL(StringPrintf("test%s", "test"), "testtest");
51   BOOST_CHECK_EQUAL(StringPrintf("test%d", 1), "test1");
52   BOOST_CHECK_EQUAL(StringPrintf("test%.3f", 1.234), "test1.234");
53   BOOST_CHECK_EQUAL(StringPrintf("%s%s", "test", "test"), "testtest");
54   BOOST_CHECK_EQUAL(StringPrintf("%d%s", 1, "test"), "1test");
55   BOOST_CHECK_EQUAL(StringPrintf("%.3f%s", 1.234, "test"), "1.234test");
56 }
57 
BOOST_AUTO_TEST_CASE(TestStringReplace)58 BOOST_AUTO_TEST_CASE(TestStringReplace) {
59   BOOST_CHECK_EQUAL(StringReplace("test", "-", ""), "test");
60   BOOST_CHECK_EQUAL(StringReplace("test", "t", "a"), "aesa");
61   BOOST_CHECK_EQUAL(StringReplace("test", "t", "---"), "---es---");
62   BOOST_CHECK_EQUAL(StringReplace("test", "", "a"), "test");
63   BOOST_CHECK_EQUAL(StringReplace("test", "", ""), "test");
64   BOOST_CHECK_EQUAL(StringReplace("ttt", "ttt", "+++"), "+++");
65 }
66 
BOOST_AUTO_TEST_CASE(TestStringGetAfter)67 BOOST_AUTO_TEST_CASE(TestStringGetAfter) {
68   BOOST_CHECK_EQUAL(StringGetAfter("test", ""), "test");
69   BOOST_CHECK_EQUAL(StringGetAfter("test", "notinit"), "");
70   BOOST_CHECK_EQUAL(StringGetAfter("test", "e"), "st");
71   BOOST_CHECK_EQUAL(StringGetAfter("test, multiple tests", "test"), "s");
72   BOOST_CHECK_EQUAL(StringGetAfter("", ""), "");
73   BOOST_CHECK_EQUAL(StringGetAfter("path/to/dataset/sub1/image.png", "sub1/"), "image.png");
74 }
75 
BOOST_AUTO_TEST_CASE(TestStringSplit)76 BOOST_AUTO_TEST_CASE(TestStringSplit) {
77   const std::vector<std::string> list1 = StringSplit("1,2,3,4,5 , 6", ",");
78   BOOST_CHECK_EQUAL(list1.size(), 6);
79   BOOST_CHECK_EQUAL(list1[0], "1");
80   BOOST_CHECK_EQUAL(list1[1], "2");
81   BOOST_CHECK_EQUAL(list1[2], "3");
82   BOOST_CHECK_EQUAL(list1[3], "4");
83   BOOST_CHECK_EQUAL(list1[4], "5 ");
84   BOOST_CHECK_EQUAL(list1[5], " 6");
85   const std::vector<std::string> list2 = StringSplit("1,2,3,4,5 , 6", "");
86   BOOST_CHECK_EQUAL(list2.size(), 1);
87   BOOST_CHECK_EQUAL(list2[0], "1,2,3,4,5 , 6");
88   const std::vector<std::string> list3 = StringSplit("1,,2,,3,4,5 , 6", ",");
89   BOOST_CHECK_EQUAL(list3.size(), 6);
90   BOOST_CHECK_EQUAL(list3[0], "1");
91   BOOST_CHECK_EQUAL(list3[1], "2");
92   BOOST_CHECK_EQUAL(list3[2], "3");
93   BOOST_CHECK_EQUAL(list3[3], "4");
94   BOOST_CHECK_EQUAL(list3[4], "5 ");
95   BOOST_CHECK_EQUAL(list3[5], " 6");
96   const std::vector<std::string> list4 = StringSplit("1,,2,,3,4,5 , 6", ",,");
97   BOOST_CHECK_EQUAL(list4.size(), 6);
98   BOOST_CHECK_EQUAL(list4[0], "1");
99   BOOST_CHECK_EQUAL(list4[1], "2");
100   BOOST_CHECK_EQUAL(list4[2], "3");
101   BOOST_CHECK_EQUAL(list4[3], "4");
102   BOOST_CHECK_EQUAL(list4[4], "5 ");
103   BOOST_CHECK_EQUAL(list4[5], " 6");
104   const std::vector<std::string> list5 = StringSplit("1,,2,,3,4,5 , 6", ", ");
105   BOOST_CHECK_EQUAL(list5.size(), 6);
106   BOOST_CHECK_EQUAL(list5[0], "1");
107   BOOST_CHECK_EQUAL(list5[1], "2");
108   BOOST_CHECK_EQUAL(list5[2], "3");
109   BOOST_CHECK_EQUAL(list5[3], "4");
110   BOOST_CHECK_EQUAL(list5[4], "5");
111   BOOST_CHECK_EQUAL(list5[5], "6");
112   const std::vector<std::string> list6 = StringSplit(",1,,2,,3,4,5 , 6 ", ", ");
113   BOOST_CHECK_EQUAL(list6.size(), 8);
114   BOOST_CHECK_EQUAL(list6[0], "");
115   BOOST_CHECK_EQUAL(list6[1], "1");
116   BOOST_CHECK_EQUAL(list6[2], "2");
117   BOOST_CHECK_EQUAL(list6[3], "3");
118   BOOST_CHECK_EQUAL(list6[4], "4");
119   BOOST_CHECK_EQUAL(list6[5], "5");
120   BOOST_CHECK_EQUAL(list6[6], "6");
121   BOOST_CHECK_EQUAL(list6[7], "");
122 }
123 
BOOST_AUTO_TEST_CASE(TestStringStartsWith)124 BOOST_AUTO_TEST_CASE(TestStringStartsWith) {
125   BOOST_CHECK(!StringStartsWith("", ""));
126   BOOST_CHECK(!StringStartsWith("a", ""));
127   BOOST_CHECK(!StringStartsWith("", "a"));
128   BOOST_CHECK(StringStartsWith("a", "a"));
129   BOOST_CHECK(StringStartsWith("aa", "a"));
130   BOOST_CHECK(StringStartsWith("aa", "aa"));
131   BOOST_CHECK(StringStartsWith("aaaaaaaaa", "aa"));
132 }
133 
BOOST_AUTO_TEST_CASE(TestStringStrim)134 BOOST_AUTO_TEST_CASE(TestStringStrim) {
135   TEST_STRING_INPLACE(StringTrim, "", "");
136   TEST_STRING_INPLACE(StringTrim, " ", "");
137   TEST_STRING_INPLACE(StringTrim, "a", "a");
138   TEST_STRING_INPLACE(StringTrim, " a", "a");
139   TEST_STRING_INPLACE(StringTrim, "a ", "a");
140   TEST_STRING_INPLACE(StringTrim, " a ", "a");
141   TEST_STRING_INPLACE(StringTrim, "  a  ", "a");
142   TEST_STRING_INPLACE(StringTrim, "aa  ", "aa");
143   TEST_STRING_INPLACE(StringTrim, "a  a  ", "a  a");
144   TEST_STRING_INPLACE(StringTrim, "a  a  a ", "a  a  a");
145   TEST_STRING_INPLACE(StringTrim, "\n\r\t", "");
146 }
147 
BOOST_AUTO_TEST_CASE(TestStringLeftString)148 BOOST_AUTO_TEST_CASE(TestStringLeftString) {
149   TEST_STRING_INPLACE(StringLeftTrim, "", "");
150   TEST_STRING_INPLACE(StringLeftTrim, " ", "");
151   TEST_STRING_INPLACE(StringLeftTrim, "a", "a");
152   TEST_STRING_INPLACE(StringLeftTrim, " a", "a");
153   TEST_STRING_INPLACE(StringLeftTrim, "a ", "a ");
154   TEST_STRING_INPLACE(StringLeftTrim, " a ", "a ");
155   TEST_STRING_INPLACE(StringLeftTrim, "  a  ", "a  ");
156   TEST_STRING_INPLACE(StringLeftTrim, "aa  ", "aa  ");
157   TEST_STRING_INPLACE(StringLeftTrim, "a  a  ", "a  a  ");
158   TEST_STRING_INPLACE(StringLeftTrim, "  a  a", "a  a");
159   TEST_STRING_INPLACE(StringLeftTrim, "a  a  a ", "a  a  a ");
160   TEST_STRING_INPLACE(StringTrim, "\n\r\ta", "a");
161 }
162 
BOOST_AUTO_TEST_CASE(TestStringStrimRight)163 BOOST_AUTO_TEST_CASE(TestStringStrimRight) {
164   TEST_STRING_INPLACE(StringRightTrim, "", "");
165   TEST_STRING_INPLACE(StringRightTrim, " ", "");
166   TEST_STRING_INPLACE(StringRightTrim, "a", "a");
167   TEST_STRING_INPLACE(StringRightTrim, " a", " a");
168   TEST_STRING_INPLACE(StringRightTrim, "a ", "a");
169   TEST_STRING_INPLACE(StringRightTrim, " a ", " a");
170   TEST_STRING_INPLACE(StringRightTrim, "  a  ", "  a");
171   TEST_STRING_INPLACE(StringRightTrim, "aa  ", "aa");
172   TEST_STRING_INPLACE(StringRightTrim, "a  a  ", "a  a");
173   TEST_STRING_INPLACE(StringRightTrim, "a  a  a ", "a  a  a");
174   TEST_STRING_INPLACE(StringTrim, "a\n\r\t", "a");
175 }
176 
BOOST_AUTO_TEST_CASE(TestStringToLower)177 BOOST_AUTO_TEST_CASE(TestStringToLower) {
178   TEST_STRING_INPLACE(StringToLower, "", "");
179   TEST_STRING_INPLACE(StringToLower, " ", " ");
180   TEST_STRING_INPLACE(StringToLower, "a", "a");
181   TEST_STRING_INPLACE(StringToLower, " a", " a");
182   TEST_STRING_INPLACE(StringToLower, "a ", "a ");
183   TEST_STRING_INPLACE(StringToLower, " a ", " a ");
184   TEST_STRING_INPLACE(StringToLower, "aa  ", "aa  ");
185   TEST_STRING_INPLACE(StringToLower, "A", "a");
186   TEST_STRING_INPLACE(StringToLower, " A", " a");
187   TEST_STRING_INPLACE(StringToLower, "A ", "a ");
188   TEST_STRING_INPLACE(StringToLower, " A ", " a ");
189   TEST_STRING_INPLACE(StringToLower, "AA  ", "aa  ");
190   TEST_STRING_INPLACE(StringToLower, "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
191                       "abcdefghijklmnopqrstuvwxyz");
192   TEST_STRING_INPLACE(StringToLower, "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ",
193                       "0123456789 abcdefghijklmnopqrstuvwxyz");
194 }
195 
BOOST_AUTO_TEST_CASE(TestStringToUpper)196 BOOST_AUTO_TEST_CASE(TestStringToUpper) {
197   TEST_STRING_INPLACE(StringToUpper, "", "");
198   TEST_STRING_INPLACE(StringToUpper, " ", " ");
199   TEST_STRING_INPLACE(StringToUpper, "A", "A");
200   TEST_STRING_INPLACE(StringToUpper, " A", " A");
201   TEST_STRING_INPLACE(StringToUpper, "A ", "A ");
202   TEST_STRING_INPLACE(StringToUpper, " A ", " A ");
203   TEST_STRING_INPLACE(StringToUpper, "AA  ", "AA  ");
204   TEST_STRING_INPLACE(StringToUpper, "a", "A");
205   TEST_STRING_INPLACE(StringToUpper, " a", " A");
206   TEST_STRING_INPLACE(StringToUpper, "a ", "A ");
207   TEST_STRING_INPLACE(StringToUpper, " a ", " A ");
208   TEST_STRING_INPLACE(StringToUpper, "aa  ", "AA  ");
209   TEST_STRING_INPLACE(StringToUpper, "abcdefghijklmnopqrstuvwxyz",
210                       "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
211   TEST_STRING_INPLACE(StringToUpper, "0123456789 abcdefghijklmnopqrstuvwxyz",
212                       "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ");
213 }
214 
BOOST_AUTO_TEST_CASE(TestStringContains)215 BOOST_AUTO_TEST_CASE(TestStringContains) {
216   BOOST_CHECK(StringContains("", ""));
217   BOOST_CHECK(StringContains("a", ""));
218   BOOST_CHECK(StringContains("a", "a"));
219   BOOST_CHECK(StringContains("ab", "a"));
220   BOOST_CHECK(StringContains("ab", "ab"));
221   BOOST_CHECK(!StringContains("", "a"));
222   BOOST_CHECK(!StringContains("ab", "c"));
223 }
224