1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright 2006 - 2021, Paul Beckingham, Federico Hernandez.
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included
13 // in all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 // SOFTWARE.
22 //
23 // http://www.opensource.org/licenses/mit-license.php
24 //
25 ////////////////////////////////////////////////////////////////////////////////
26
27 #include <cmake.h>
28 #include <shared.h>
29 #include <test.h>
30
31 ////////////////////////////////////////////////////////////////////////////////
main(int,char **)32 int main (int, char**)
33 {
34 UnitTest t (204);
35
36 // void wrapText (std::vector <std::string>& lines, const std::string& text, const int width, bool hyphenate)
37 std::string text = "This is a test of the line wrapping code.";
38 std::vector <std::string> lines;
39 wrapText (lines, text, 10, true);
40 t.is (lines.size (), (size_t) 5, "wrapText 'This is a test of the line wrapping code.' -> total 5 lines");
41 t.is (lines[0], "This is a", "wrapText line 0 -> 'This is a'");
42 t.is (lines[1], "test of", "wrapText line 1 -> 'test of'");
43 t.is (lines[2], "the line", "wrapText line 2 -> 'the line'");
44 t.is (lines[3], "wrapping", "wrapText line 3 -> 'wrapping'");
45 t.is (lines[4], "code.", "wrapText line 4 -> 'code.'");
46
47 text = "This ☺ is a test of utf8 line extraction.";
48 lines.clear ();
49 wrapText (lines, text, 7, true);
50 t.is (lines.size (), (size_t) 7, "wrapText 'This ☺ is a test of utf8 line extraction.' -> total 7 lines");
51 t.is (lines[0], "This ☺", "wrapText line 0 -> 'This ☺'");
52 t.is (lines[1], "is a", "wrapText line 1 -> 'is a'");
53 t.is (lines[2], "test of", "wrapText line 2 -> 'test of'");
54 t.is (lines[3], "utf8", "wrapText line 3 -> 'utf8'");
55 t.is (lines[4], "line", "wrapText line 4 -> 'line'");
56 t.is (lines[5], "extrac-", "wrapText line 5 -> 'extrac-'");
57 t.is (lines[6], "tion.", "wrapText line 6 -> 'tion.'");
58
59 text = "one two three\n four";
60 lines.clear ();
61 wrapText (lines, text, 13, true);
62 t.is (lines.size (), (size_t) 2, "wrapText 'one two three\\n four' -> 2 lines");
63 t.is (lines[0], "one two three", "wrapText line 0 -> 'one two three'");
64 t.is (lines[1], " four", "wrapText line 1 -> ' four'");
65
66 // void extractLine (std::string& text, std::string& line, int length, bool hyphenate, unsigned int& offset)
67 text = "This ☺ is a test of utf8 line extraction.";
68 unsigned int offset = 0;
69 std::string line;
70 extractLine (line, text, 7, true, offset);
71 t.is (line, "This ☺", "extractLine 7 'This ☺ is a test of utf8 line extraction.' -> 'This ☺'");
72
73 // void extractLine (std::string& text, std::string& line, int length, bool hyphenate, unsigned int& offset)
74 text = "line 1\nlengthy second line that exceeds width";
75 offset = 0;
76 extractLine (line, text, 10, true, offset);
77 t.is (line, "line 1", "extractLine 10 'line 1\\nlengthy second line that exceeds width' -> 'line 1'");
78
79 extractLine (line, text, 10, true, offset);
80 t.is (line, "lengthy", "extractLine 10 'lengthy second line that exceeds width' -> 'lengthy'");
81
82 extractLine (line, text, 10, true, offset);
83 t.is (line, "second", "extractLine 10 'second line that exceeds width' -> 'second'");
84
85 extractLine (line, text, 10, true, offset);
86 t.is (line, "line that", "extractLine 10 'line that exceeds width' -> 'line that'");
87
88 extractLine (line, text, 10, true, offset);
89 t.is (line, "exceeds", "extractLine 10 'exceeds width' -> 'exceeds'");
90
91 extractLine (line, text, 10, true, offset);
92 t.is (line, "width", "extractLine 10 'width' -> 'width'");
93
94 t.notok (extractLine (line, text, 10, true, offset), "extractLine 10 '' -> ''");
95
96 text = "AAAAAAAAAABBBBBBBBBB";
97 offset = 0;
98 extractLine (line, text, 10, true, offset);
99 t.is (line, "AAAAAAAAA-", "extractLine hyphenated unbreakable line");
100 t.diag (line);
101
102 /*
103 TODO Resolve above against below, from Taskwarrior 2.6.0
104
105 // void extractLine (std::string& text, std::string& line, int length, bool hyphenate, unsigned int& offset)
106 std::string text = "This ☺ is a test of utf8 line extraction.";
107 unsigned int offset = 0;
108 std::string line;
109 extractLine (line, text, 7, true, offset);
110 t.is (line, "This ☺", "extractLine 7 'This ☺ is a test of utf8 line extraction.' -> 'This ☺'");
111
112 // void extractLine (std::string& text, std::string& line, int length, bool hyphenate, unsigned int& offset)
113 text = "line 1\nlengthy second line that exceeds width";
114 offset = 0;
115 extractLine (line, text, 10, true, offset);
116 t.is (line, "line 1", "extractLine 10 'line 1\\nlengthy second line that exceeds width' -> 'line 1'");
117
118 extractLine (line, text, 10, true, offset);
119 t.is (line, "lengthy", "extractLine 10 'lengthy second line that exceeds width' -> 'lengthy'");
120
121 extractLine (line, text, 10, true, offset);
122 t.is (line, "second", "extractLine 10 'second line that exceeds width' -> 'second'");
123
124 extractLine (line, text, 10, true, offset);
125 t.is (line, "line that", "extractLine 10 'line that exceeds width' -> 'line that'");
126
127 extractLine (line, text, 10, true, offset);
128 t.is (line, "exceeds", "extractLine 10 'exceeds width' -> 'exceeds'");
129
130 extractLine (line, text, 10, true, offset);
131 t.is (line, "width", "extractLine 10 'width' -> 'width'");
132
133 t.notok (extractLine (line, text, 10, true, offset), "extractLine 10 '' -> ''");
134
135 text = "AAAAAAAAAABBBBBBBBBB";
136 offset = 0;
137 extractLine (line, text, 10, true, offset);
138 t.is (line, "AAAAAAAAA-", "extractLine hyphenated unbreakable line 'AAAAAAAAAABBBBBBBBBB'/10 -> 'AAAAAAAAA-'");
139
140 extractLine (line, text, 10, true, offset);
141 t.is (line, "ABBBBBBBB-", "extractLine hyphenated unbreakable line 'AAAAAAAAAABBBBBBBBBB'/10 -> 'ABBBBBBBB-'");
142
143 extractLine (line, text, 10, true, offset);
144 t.is (line, "BB", "extractLine hyphenated unbreakable line 'AAAAAAAAAABBBBBBBBBB'/10 -> 'BB'");
145
146 text = "4444 333 ";
147 offset = 0;
148 while (extractLine (line, text, 9, true, offset))
149 std::cout << "# line '" << line << "' offset " << offset << "\n";
150 */
151
152 // std::vector <std::string> split (const std::string& input, const char delimiter)
153 std::string unsplit;
154 std::vector <std::string> items = split (unsplit, '-');
155 t.is (items.size (), (size_t) 0, "split '' '-' -> 0 items");
156
157 unsplit = "a";
158 items = split (unsplit, '-');
159 t.is (items.size (), (size_t) 1, "split 'a' '-' -> 1 item");
160 t.is (items[0], "a", "split 'a' '-' -> 'a'");
161
162 items = split (unsplit, '-');
163 t.is (items.size (), (size_t) 1, "split 'a' '-' -> 1 item");
164 t.is (items[0], "a", "split 'a' '-' -> 'a'");
165
166 unsplit = "-";
167 items = split (unsplit, '-');
168 t.is (items.size (), (size_t) 2, "split '-' '-' -> '' ''");
169 t.is (items[0], "", "split '-' '-' -> [0] ''");
170 t.is (items[1], "", "split '-' '-' -> [1] ''");
171
172 unsplit = "-a-bc--def";
173 items = split (unsplit, '-');
174 t.is (items.size (), (size_t) 5, "split '-a-bc--def' '-' -> '' 'a' 'bc' '' 'def'");
175 t.is (items[0], "", "split '-a-bc--def' '-' -> [0] ''");
176 t.is (items[1], "a", "split '-a-bc--def' '-' -> [1] 'a'");
177 t.is (items[2], "bc", "split '-a-bc--def' '-' -> [2] 'bc'");
178 t.is (items[3], "", "split '-a-bc--def' '-' -> [3] ''");
179 t.is (items[4], "def", "split '-a-bc--def' '-' -> [4] 'def'");
180
181 // std::vector <std::string> split (const std::string& input);
182 unsplit = "";
183 items = split (unsplit);
184 t.is (items.size (), (size_t) 0, "split '' -> 0 items");
185
186 unsplit = "abc";
187 items = split (unsplit);
188 t.is (items.size (), (size_t) 1, "split 'abc' -> 1 item");
189 t.is (items[0], "abc", "split 'abc' -> [0] 'abc'");
190
191 unsplit = "a b c";
192 items = split (unsplit);
193 t.is (items.size (), (size_t) 3, "split 'a b c' -> 3 items");
194 t.is (items[0], "a", "split 'a b c' -> [0] 'a'");
195 t.is (items[1], "b", "split 'a b c' -> [1] 'b'");
196 t.is (items[2], "c", "split 'a b c' -> [2] 'c'");
197
198 unsplit = " a b c ";
199 items = split (unsplit);
200 t.is (items.size (), (size_t) 3, "split ' a b c ' -> 3 items");
201 t.is (items[0], "a", "split ' a b c ' -> [0] 'a'");
202 t.is (items[1], "b", "split ' a b c ' -> [1] 'b'");
203 t.is (items[2], "c", "split ' a b c ' -> [2] 'c'");
204
205 // std::string join (const std::string&r, const std::vector<int>&)
206 // std::string join (const std::string&r, const std::vector<std::string>&)
207 std::vector <std::string> unjoined;
208 std::string joined;
209
210 joined = join ("", unjoined);
211 t.is (joined.length (), (size_t) 0, "join -> length 0");
212 t.is (joined, "", "join -> ''");
213
214 unjoined = {"", "a", "bc", "def"};
215 joined = join ("", unjoined);
216 t.is (joined.length (), (size_t) 6, "join '' 'a' 'bc' 'def' -> length 6");
217 t.is (joined, "abcdef", "join '' 'a' 'bc' 'def' -> 'abcdef'");
218
219 joined = join ("-", unjoined);
220 t.is (joined.length (), (size_t) 9, "join '' - 'a' - 'bc' - 'def' -> length 9");
221 t.is (joined, "-a-bc-def", "join '' - 'a' - 'bc' - 'def' -> '-a-bc-def'");
222
223 std::vector <int> unjoined_ints {1, 2, 3, 4};
224 t.is (join ("-", unjoined_ints), "1-2-3-4", "join 1 - 2 - 3 - 4 -> '1-2-3-4'");
225
226 // std::string trim (const std::string&);
227 t.is (trim ("one"), "one", "trim 'one' --> 'one'");
228 t.is (trim (" one"), "one", "trim ' one' --> 'one'");
229 t.is (trim ("one "), "one", "trim 'one ' --> 'one'");
230 t.is (trim (" one "), "one", "trim ' one ' --> 'one'");
231 t.is (trim (""), "", "trim '' --> ''");
232 t.is (trim (" \t\r\f\nfoo\n\f\r\t "), "foo",
233 "trim ' \t\r\f\nfoo\n\f\r\t ' --> 'foo'");
234
235 t.is (trim ("abcdedcba", "abc"), "ded", "trim 'abcdedcba', 'abc' --> 'ded'");
236
237 // std::string ltrim (const std::string&);
238 t.is (ltrim ("one"), "one", "ltrim 'one' --> 'one'");
239 t.is (ltrim (" one"), "one", "ltrim ' one' --> 'one'");
240 t.is (ltrim ("one "), "one ", "ltrim 'one ' --> 'one '");
241 t.is (ltrim (" one "), "one ", "ltrim ' one ' --> 'one '");
242 t.is (ltrim (""), "", "ltrim '' --> ''");
243 t.is (ltrim (" "), "", "ltrim ' ' --> ''");
244 t.is (ltrim (" \t\r\f\nfoo\n\f\r\t "), "foo\n\f\r\t ",
245 "ltrim ' \t\r\f\nfoo\n\f\r\t ' --> 'foo\\n\\f\\r\\t '");
246
247 // std::string rtrim (const std::string&);
248 t.is (rtrim ("one"), "one", "rtrim 'one' --> 'one'");
249 t.is (rtrim (" one"), " one", "rtrim ' one' --> ' one'");
250 t.is (rtrim ("one "), "one", "rtrim 'one ' --> 'one'");
251 t.is (rtrim (" one "), " one", "rtrim ' one' --> ' one'");
252 t.is (rtrim (""), "", "rtrim '' --> ''");
253 t.is (rtrim (" "), "", "rtrim ' ' --> ''");
254 t.is (rtrim (" \t\r\f\nfoo\n\f\r\t "), " \t\r\f\nfoo",
255 "rtrim ' \t\r\f\nfoo\n\f\r\t ' --> ' \\t\\r\\f\\nfoo'");
256
257 // int longestWord (const std::string&)
258 t.is (longestWord (" "), 0, "longestWord ( ) --> 0");
259 t.is (longestWord ("this is a test"), 4, "longestWord (this is a test) --> 4");
260 t.is (longestWord ("this is a better test"), 6, "longestWord (this is a better test) --> 6");
261 t.is (longestWord ("house Çirçös clown"), 6, "longestWord (Çirçös) --> 6");
262
263 // int longestLine (const std::string&)
264 t.is (longestLine ("one two three four"), 18, "longestLine (one two three four) --> 18");
265 t.is (longestLine ("one\ntwo three four"), 14, "longestLine (one\\ntwo three four) --> 14");
266 t.is (longestLine ("one\ntwo\nthree\nfour"), 5, "longestLine (one\\ntwo\\nthree\\nfour) --> 5");
267
268 // bool compare (const std::string&, const std::string&, bool sensitive = true);
269 t.notok (compare ("a", "b"), "compare 'a' : 'b' --> false");
270 t.notok (compare ("a", ""), "compare 'a' : '' --> false");
271 t.notok (compare ("", "b"), "compare '' : 'b' --> false");
272 t.ok (compare ("", ""), "compare '' : '' --> true");
273 t.notok (compare ("A", "a"), "compare 'A' : 'a' --> false");
274 t.notok (compare ("A", "a", true), "compare sensitive 'A' : 'a' --> false");
275 t.ok (compare ("A", "a", false), "compare !sensitive 'A' : 'a' --> true");
276
277 // bool closeEnough (const std::string&, const std::string&, unsigned int minLength = 0);
278 t.ok (closeEnough ("foobar", "foobar"), "closeEnough foobar == foobar");
279 t.ok (closeEnough ("foobar", "foobar", 0), "closeEnough foobar == foobar,0");
280 t.ok (closeEnough ("foobar", "foobar", 1), "closeEnough foobar == foobar,1");
281 t.ok (closeEnough ("foobar", "foobar", 2), "closeEnough foobar == foobar,2");
282 t.ok (closeEnough ("foobar", "foobar", 3), "closeEnough foobar == foobar,3");
283 t.ok (closeEnough ("foobar", "foobar", 4), "closeEnough foobar == foobar,4");
284 t.ok (closeEnough ("foobar", "foobar", 5), "closeEnough foobar == foobar,5");
285 t.ok (closeEnough ("foobar", "foobar", 6), "closeEnough foobar == foobar,6");
286 t.ok (closeEnough ("foobar", "foo", 3), "closeEnough foobar == foo,3");
287
288 // int matchLength (const std::string&, const std::string&, unsigned int minLength = 0);
289 t.is (matchLength ("", "foobar"), 0, "matchLength '' == foobar --> 0");
290 t.is (matchLength ("f", "foobar"), 1, "matchLength f == foobar --> 1");
291 t.is (matchLength ("fo", "foobar"), 2, "matchLength fo == foobar --> 2");
292 t.is (matchLength ("foo", "foobar"), 3, "matchLength foo == foobar --> 3");
293 t.is (matchLength ("foob", "foobar"), 4, "matchLength foob == foobar --> 4");
294 t.is (matchLength ("fooba", "foobar"), 5, "matchLength fooba == foobar --> 5");
295 t.is (matchLength ("foobar", "foobar"), 6, "matchLength foobar == foobar --> 6");
296 t.is (matchLength ("foobar", "fooba"), 5, "matchLength foobar == fooba --> 5");
297 t.is (matchLength ("foobar", "foob"), 4, "matchLength foobar == foob --> 4");
298 t.is (matchLength ("foobar", "foo"), 3, "matchLength foobar == foo --> 3");
299 t.is (matchLength ("foobar", "fo"), 2, "matchLength foobar == fo --> 2");
300 t.is (matchLength ("foobar", "f"), 1, "matchLength foobar == f --> 1");
301 t.is (matchLength ("foobar", ""), 0, "matchLength foobar == '' --> 0");
302
303 t.is (matchLength ("foobar", "foodmixer"), 3, "matchLength foobar == foodmixer --> 3");
304 t.is (matchLength ("foodmixer", "foobar"), 3, "matchLength foodmixer == foobar --> 3");
305
306 // std::string lowerCase (const std::string&);
307 t.is (lowerCase (""), "", "lowerCase '' --> ''");
308 t.is (lowerCase ("a"), "a", "lowerCase 'a' --> 'a'");
309 t.is (lowerCase ("aA"), "aa", "lowerCase 'aA' --> 'aa'");
310 t.is (lowerCase ("A"), "a", "lowerCase 'A' --> 'a'");
311 t.is (lowerCase ("$"), "$", "lowerCase '$' --> '$'");
312
313 // std::string upperCase (const std::string&);
314 t.is (upperCase (""), "", "upperCase '' --> ''");
315 t.is (upperCase ("a"), "A", "upperCase 'a' --> 'A'");
316 t.is (upperCase ("aA"), "AA", "upperCase 'aA' --> 'AA'");
317 t.is (upperCase ("A"), "A", "upperCase 'A' --> 'A'");
318 t.is (upperCase ("$"), "$", "upperCase '$' --> '$'");
319
320 // std::string upperCaseFirst (const std::string&);
321 t.is (upperCaseFirst (""), "", "upperCaseFirst '' --> ''");
322 t.is (upperCaseFirst ("a"), "A", "upperCaseFirst 'a' --> 'A'");
323 t.is (upperCaseFirst ("A"), "A", "upperCaseFirst 'A' --> 'A'");
324 t.is (upperCaseFirst ("aa"), "Aa", "upperCaseFirst 'aa' --> 'Aa'");
325 t.is (upperCaseFirst ("$"), "$", "upperCaseFirst '$' --> '$'");
326
327 // std::string str_replace (const std::string&, const std::string&, const std::string&);
328 std::string input = "Lorem ipsum dolor sit amet, est aliquip scaevola dignissim in, vim nominavi electram te.";
329 t.is (str_replace (input, "x", "X"),
330 "Lorem ipsum dolor sit amet, est aliquip scaevola dignissim in, vim nominavi electram te.",
331 "str_replace 'x' -- 'X' (NOP)");
332
333 t.is (str_replace (input, "e", "E"),
334 "LorEm ipsum dolor sit amEt, Est aliquip scaEvola dignissim in, vim nominavi ElEctram tE.",
335 "str_replace 'e' -- 'E'");
336
337 // std::string::size_type find (const std::string&, const std::string&, bool sensitive = true);
338 // std::string::size_type find (const std::string&, const std::string&, std::string::size_type, bool sensitive = true);
339 // Make sure degenerate cases are handled.
340 t.is ((int) find ("foo", ""), (int) 0, "find foo !contains ''");
341 t.is ((int) find ("", "foo"), (int) std::string::npos, "find '' !contains foo");
342
343 // Make sure the default is case-sensitive.
344 t.is ((int) find ("foo", "fo"), 0, "find foo contains fo");
345 t.is ((int) find ("foo", "FO"), (int) std::string::npos, "find foo !contains fo");
346
347 // Test case-sensitive.
348 t.is ((int) find ("foo", "xx", true), (int) std::string::npos, "find foo !contains xx");
349 t.is ((int) find ("foo", "oo", true), 1, "find foo contains oo");
350
351 t.is ((int) find ("foo", "fo", true), 0, "find foo contains fo");
352 t.is ((int) find ("foo", "FO", true), (int) std::string::npos, "find foo !contains fo");
353 t.is ((int) find ("FOO", "fo", true), (int) std::string::npos, "find foo !contains fo");
354 t.is ((int) find ("FOO", "FO", true), 0, "find foo contains fo");
355
356 // Test case-insensitive.
357 t.is ((int) find ("foo", "xx", false), (int) std::string::npos, "find foo !contains xx (caseless)");
358 t.is ((int) find ("foo", "oo", false), 1, "find foo contains oo (caseless)");
359
360 t.is ((int) find ("foo", "fo", false), 0, "find foo contains fo (caseless)");
361 t.is ((int) find ("foo", "FO", false), 0, "find foo contains FO (caseless)");
362 t.is ((int) find ("FOO", "fo", false), 0, "find FOO contains fo (caseless)");
363 t.is ((int) find ("FOO", "FO", false), 0, "find FOO contains FO (caseless)");
364
365 // Test start offset.
366 t.is ((int) find ("one two three", "e", 3, true), (int) 11, "find offset obeyed");
367 t.is ((int) find ("one two three", "e", 11, true), (int) 11, "find offset obeyed");
368
369 t.is ((int) find ("one two three", "e", 3, false), (int) 11, "find offset obeyed");
370 t.is ((int) find ("one two three", "e", 11, false), (int) 11, "find offset obeyed");
371
372 // Test osName actually recognizes OS.
373 t.ok (osName () != "<unknown>", "osName: Recognizes OS as: " + osName ());
374
375 // Test cppCompliance actually recognizes compliance level.
376 t.ok (cppCompliance () != "non-compliant", "cppCompliance: Recognizes compiler compliance level as: " + cppCompliance ());
377
378 // Test IPv4/IPv6 address parsing.
379 std::string address;
380 int port;
381 input = "127.0.0.1";
382 t.ok (isIPv4Address (input, address, port), "isIPv4Address " + input + " --> yes");
383 t.is (address, "127.0.0.1", "isIPv4Address " + input + " --> address correct");
384 t.is (port, 0, "isIPv4Address " + input + " --> port correct");
385 t.notok (isIPv6Address (input, address, port), "isIPv6Address " + input + " --> no");
386
387 input = "127.0.0.1:80";
388 t.ok (isIPv4Address (input, address, port), "isIPv4Address " + input + " --> yes");
389 t.is (address, "127.0.0.1", "isIPv4Address " + input + " --> address correct");
390 t.is (port, 80, "isIPv4Address " + input + " --> port correct");
391 t.notok (isIPv6Address (input, address, port), "isIPv6Address " + input + " --> no");
392
393 input = "::1";
394 t.notok (isIPv4Address (input, address, port), "isIPv4Address " + input + " --> no");
395 t.ok (isIPv6Address (input, address, port), "isIPv6Address " + input + " --> yes");
396 t.is (address, "::1", "isIPv6Address " + input + " --> address correct");
397 t.is (port, 0, "isIPv6Address " + input + " --> port correct");
398
399 input = "[::1]:80";
400 t.notok (isIPv4Address (input, address, port), "isIPv4Address " + input + " --> no");
401 t.ok (isIPv6Address (input, address, port), "isIPv6Address " + input + " --> yes");
402 t.is (address, "::1", "isIPv6Address " + input + " --> address correct");
403 t.is (port, 80, "isIPv6Address " + input + " --> port correct");
404
405 input = "2605:2700:0:3::4713:93e3";
406 t.notok (isIPv4Address (input, address, port), "isIPv4Address " + input + " --> no");
407 t.ok (isIPv6Address (input, address, port), "isIPv6Address " + input + " --> yes");
408 t.is (address, "2605:2700:0:3::4713:93e3", "isIPv6Address " + input + " --> address correct");
409 t.is (port, 0, "isIPv6Address " + input + " --> port correct");
410
411 input = "[2605:2700:0:3::4713:93e3]:80";
412 t.notok (isIPv4Address (input, address, port), "isIPv4Address " + input + " --> no");
413 t.ok (isIPv6Address (input, address, port), "isIPv6Address " + input + " --> yes");
414 t.is (address, "2605:2700:0:3::4713:93e3", "isIPv6Address " + input + " --> address correct");
415 t.is (port, 80, "isIPv6Address " + input + " --> port correct");
416
417 input = "2001:db8:85a3:0:0:8a2e:370:7334";
418 t.notok (isIPv4Address (input, address, port), "isIPv4Address " + input + " --> no");
419 t.ok (isIPv6Address (input, address, port), "isIPv6Address " + input + " --> yes");
420 t.is (address, "2001:db8:85a3:0:0:8a2e:370:7334", "isIPv6Address " + input + " --> address correct");
421 t.is (port, 0, "isIPv6Address " + input + " --> port correct");
422
423 input = "2001:db8:85a3::8a2e:370:7334";
424 t.notok (isIPv4Address (input, address, port), "isIPv4Address " + input + " --> no");
425 t.ok (isIPv6Address (input, address, port), "isIPv6Address " + input + " --> yes");
426 t.is (address, "2001:db8:85a3::8a2e:370:7334", "isIPv6Address " + input + " --> address correct");
427 t.is (port, 0, "isIPv6Address " + input + " --> port correct");
428
429 input = "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443";
430 t.notok (isIPv4Address (input, address, port), "isIPv4Address " + input + " --> no");
431 t.ok (isIPv6Address (input, address, port), "isIPv6Address " + input + " --> yes");
432 t.is (address, "2001:db8:85a3:8d3:1319:8a2e:370:7348", "isIPv6Address " + input + " --> address correct");
433 t.is (port, 443, "isIPv6Address " + input + " --> port correct");
434
435 input = "::ffff:192.168.0.1";
436 t.notok (isIPv4Address (input, address, port), "isIPv4Address " + input + " --> no");
437 t.ok (isIPv6Address (input, address, port), "isIPv6Address " + input + " --> yes");
438 t.is (address, "::ffff:192.168.0.1", "isIPv6Address " + input + " --> address correct");
439 t.is (port, 0, "isIPv6Address " + input + " --> port correct");
440
441 input = "[::ffff:71.19.147.227]:80";
442 t.notok (isIPv4Address (input, address, port), "isIPv4Address " + input + " --> no");
443 t.ok (isIPv6Address (input, address, port), "isIPv6Address " + input + " --> yes");
444 t.is (address, "::ffff:71.19.147.227", "isIPv6Address " + input + " --> address correct");
445 t.is (port, 80, "isIPv6Address " + input + " --> port correct");
446
447 input = "::";
448 t.notok (isIPv4Address (input, address, port), "isIPv4Address " + input + " --> no");
449 t.ok (isIPv6Address (input, address, port), "isIPv6Address " + input + " --> yes");
450 t.is (address, "::", "isIPv6Address " + input + " --> address correct");
451 t.is (port, 00, "isIPv6Address " + input + " --> port correct");
452
453 return 0;
454 }
455
456 ////////////////////////////////////////////////////////////////////////////////
457