PageRenderTime 59ms CodeModel.GetById 19ms app.highlight 35ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llui/tests/llurlentry_test.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 864 lines | 605 code | 176 blank | 83 comment | 3 complexity | 5bb79c50139657e09a310d2ddfe67b1b MD5 | raw file
  1/**
  2 * @file llurlentry_test.cpp
  3 * @author Martin Reddy
  4 * @brief Unit tests for LLUrlEntry objects
  5 *
  6 * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  7 * Second Life Viewer Source Code
  8 * Copyright (C) 2010, Linden Research, Inc.
  9 * 
 10 * This library is free software; you can redistribute it and/or
 11 * modify it under the terms of the GNU Lesser General Public
 12 * License as published by the Free Software Foundation;
 13 * version 2.1 of the License only.
 14 * 
 15 * This library is distributed in the hope that it will be useful,
 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 18 * Lesser General Public License for more details.
 19 * 
 20 * You should have received a copy of the GNU Lesser General Public
 21 * License along with this library; if not, write to the Free Software
 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 23 * 
 24 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 25 * $/LicenseInfo$
 26 */
 27
 28#include "linden_common.h"
 29#include "../llurlentry.h"
 30#include "../lluictrl.h"
 31#include "llurlentry_stub.cpp"
 32#include "lltut.h"
 33#include "../lluicolortable.h"
 34#include "../lluiimage.h"
 35
 36#include <boost/regex.hpp>
 37
 38typedef std::map<std::string, LLControlGroup*> settings_map_t;
 39settings_map_t LLUI::sSettingGroups;
 40
 41BOOL LLControlGroup::getBOOL(const std::string& name)
 42{
 43	return false;
 44}
 45
 46LLUIColor LLUIColorTable::getColor(const std::string& name, const LLColor4& default_color) const
 47{
 48	return LLUIColor();
 49}
 50
 51LLUIColor::LLUIColor() : mColorPtr(NULL) {}
 52
 53LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image)
 54{
 55}
 56
 57LLUIImage::~LLUIImage()
 58{
 59}
 60
 61//virtual
 62S32 LLUIImage::getWidth() const
 63{
 64	return 0;
 65}
 66
 67//virtual
 68S32 LLUIImage::getHeight() const
 69{
 70	return 0;
 71}
 72
 73namespace LLInitParam
 74{
 75	BlockDescriptor::BlockDescriptor() {}
 76	ParamDescriptor::ParamDescriptor(param_handle_t p, 
 77						merge_func_t merge_func, 
 78						deserialize_func_t deserialize_func, 
 79						serialize_func_t serialize_func,
 80						validation_func_t validation_func,
 81						inspect_func_t inspect_func,
 82						S32 min_count,
 83						S32 max_count){}
 84	ParamDescriptor::~ParamDescriptor() {}
 85
 86}
 87
 88namespace tut
 89{
 90	struct LLUrlEntryData
 91	{
 92	};
 93
 94	typedef test_group<LLUrlEntryData> factory;
 95	typedef factory::object object;
 96}
 97
 98namespace
 99{
100	tut::factory tf("LLUrlEntry");
101}
102
103namespace tut
104{
105	void testRegex(const std::string &testname, LLUrlEntryBase &entry,
106				   const char *text, const std::string &expected)
107	{
108		boost::regex regex = entry.getPattern();
109		std::string url = "";
110		boost::cmatch result;
111		bool found = boost::regex_search(text, result, regex);
112		if (found)
113		{
114			S32 start = static_cast<U32>(result[0].first - text);
115			S32 end = static_cast<U32>(result[0].second - text);
116			url = entry.getUrl(std::string(text+start, end-start));
117		}
118		ensure_equals(testname, url, expected);
119	}
120
121	void dummyCallback(const std::string &url, const std::string &label, const std::string& icon)
122	{
123	}
124
125	void testLabel(const std::string &testname, LLUrlEntryBase &entry,
126				   const char *text, const std::string &expected)
127	{
128		boost::regex regex = entry.getPattern();
129		std::string label = "";
130		boost::cmatch result;
131		bool found = boost::regex_search(text, result, regex);
132		if (found)
133		{
134			S32 start = static_cast<U32>(result[0].first - text);
135			S32 end = static_cast<U32>(result[0].second - text);
136			std::string url = std::string(text+start, end-start);
137			label = entry.getLabel(url, boost::bind(dummyCallback, _1, _2, _3));
138		}
139		ensure_equals(testname, label, expected);
140	}
141
142	void testLocation(const std::string &testname, LLUrlEntryBase &entry,
143					  const char *text, const std::string &expected)
144	{
145		boost::regex regex = entry.getPattern();
146		std::string location = "";
147		boost::cmatch result;
148		bool found = boost::regex_search(text, result, regex);
149		if (found)
150		{
151			S32 start = static_cast<U32>(result[0].first - text);
152			S32 end = static_cast<U32>(result[0].second - text);
153			std::string url = std::string(text+start, end-start);
154			location = entry.getLocation(url);
155		}
156		ensure_equals(testname, location, expected);
157	}
158
159
160	template<> template<>
161	void object::test<1>()
162	{
163		//
164		// test LLUrlEntryHTTP - standard http Urls
165		//
166		LLUrlEntryHTTP url;
167
168		testRegex("no valid url", url,
169				  "htp://slurl.com/",
170				  "");
171
172		testRegex("simple http (1)", url,
173				  "http://slurl.com/",
174				  "http://slurl.com/");
175
176		testRegex("simple http (2)", url,
177				  "http://slurl.com",
178				  "http://slurl.com");
179
180		testRegex("simple http (3)", url,
181				  "http://slurl.com/about.php",
182				  "http://slurl.com/about.php");
183
184		testRegex("simple https", url,
185				  "https://slurl.com/about.php",
186				  "https://slurl.com/about.php");
187
188		testRegex("http in text (1)", url,
189				  "XX http://slurl.com/ XX",
190				  "http://slurl.com/");
191
192		testRegex("http in text (2)", url,
193				  "XX http://slurl.com/about.php XX",
194				  "http://slurl.com/about.php");
195
196		testRegex("https in text", url,
197				  "XX https://slurl.com/about.php XX",
198				  "https://slurl.com/about.php");
199
200		testRegex("two http urls", url,
201				  "XX http://slurl.com/about.php http://secondlife.com/ XX",
202				  "http://slurl.com/about.php");
203
204		testRegex("http url with port and username", url,
205				  "XX http://nobody@slurl.com:80/about.php http://secondlife.com/ XX",
206				  "http://nobody@slurl.com:80/about.php");
207
208		testRegex("http url with port, username, and query string", url,
209				  "XX http://nobody@slurl.com:80/about.php?title=hi%20there http://secondlife.com/ XX",
210				  "http://nobody@slurl.com:80/about.php?title=hi%20there");
211
212		// note: terminating commas will be removed by LLUrlRegistry:findUrl()
213		testRegex("http url with commas in middle and terminating", url,
214				  "XX http://slurl.com/?title=Hi,There, XX",
215				  "http://slurl.com/?title=Hi,There,");
216
217		// note: terminating periods will be removed by LLUrlRegistry:findUrl()
218		testRegex("http url with periods in middle and terminating", url,
219				  "XX http://slurl.com/index.php. XX",
220				  "http://slurl.com/index.php.");
221
222		// DEV-19842: Closing parenthesis ")" breaks urls
223		testRegex("http url with brackets (1)", url,
224				  "XX http://en.wikipedia.org/wiki/JIRA_(software) XX",
225				  "http://en.wikipedia.org/wiki/JIRA_(software)");
226
227		// DEV-19842: Closing parenthesis ")" breaks urls
228		testRegex("http url with brackets (2)", url, 
229				  "XX http://jira.secondlife.com/secure/attachment/17990/eggy+avs+in+1.21.0+(93713)+public+nightly.jpg XX",
230				  "http://jira.secondlife.com/secure/attachment/17990/eggy+avs+in+1.21.0+(93713)+public+nightly.jpg");
231
232		// DEV-10353: URLs in chat log terminated incorrectly when newline in chat
233		testRegex("http url with newlines", url,
234				  "XX\nhttp://www.secondlife.com/\nXX",
235				  "http://www.secondlife.com/");
236	}
237
238	template<> template<>
239	void object::test<2>()
240	{
241		//
242		// test LLUrlEntryHTTPLabel - wiki-style http Urls with labels
243		//
244		LLUrlEntryHTTPLabel url;
245
246		testRegex("invalid wiki url [1]", url,
247				  "[http://www.example.org]",
248				  "");
249
250		testRegex("invalid wiki url [2]", url,
251				  "[http://www.example.org",
252				  "");
253
254		testRegex("invalid wiki url [3]", url,
255				  "[http://www.example.org Label",
256				  "");
257
258		testRegex("example.org with label (spaces)", url,
259				  "[http://www.example.org  Text]",
260				  "http://www.example.org");
261
262		testRegex("example.org with label (tabs)", url,
263				  "[http://www.example.org\t Text]",
264				  "http://www.example.org");
265
266		testRegex("SL http URL with label", url,
267				  "[http://www.secondlife.com/ Second Life]",
268				  "http://www.secondlife.com/");
269
270		testRegex("SL https URL with label", url,
271				  "XXX [https://www.secondlife.com/ Second Life] YYY",
272				  "https://www.secondlife.com/");
273
274		testRegex("SL http URL with label", url,
275				  "[http://www.secondlife.com/?test=Hi%20There Second Life]",
276				  "http://www.secondlife.com/?test=Hi%20There");
277	}
278
279	template<> template<>
280	void object::test<3>()
281	{
282		//
283		// test LLUrlEntrySLURL - second life URLs
284		//
285		LLUrlEntrySLURL url;
286
287		testRegex("no valid slurl [1]", url,
288				  "htp://slurl.com/secondlife/Ahern/50/50/50/",
289				  "");
290
291		testRegex("no valid slurl [2]", url,
292				  "http://slurl.com/secondlife/",
293				  "");
294
295		testRegex("no valid slurl [3]", url,
296				  "hhtp://slurl.com/secondlife/Ahern/50/FOO/50/",
297				  "");
298
299		testRegex("Ahern (50,50,50) [1]", url,
300				  "http://slurl.com/secondlife/Ahern/50/50/50/",
301				  "http://slurl.com/secondlife/Ahern/50/50/50/");
302
303		testRegex("Ahern (50,50,50) [2]", url,
304				  "XXX http://slurl.com/secondlife/Ahern/50/50/50/ XXX",
305				  "http://slurl.com/secondlife/Ahern/50/50/50/");
306
307		testRegex("Ahern (50,50,50) [3]", url,
308				  "XXX http://slurl.com/secondlife/Ahern/50/50/50 XXX",
309				  "http://slurl.com/secondlife/Ahern/50/50/50");
310
311		testRegex("Ahern (50,50,50) multicase", url,
312				  "XXX http://SLUrl.com/SecondLife/Ahern/50/50/50/ XXX",
313				  "http://SLUrl.com/SecondLife/Ahern/50/50/50/");
314
315		testRegex("Ahern (50,50) [1]", url,
316				  "XXX http://slurl.com/secondlife/Ahern/50/50/ XXX",
317				  "http://slurl.com/secondlife/Ahern/50/50/");
318
319		testRegex("Ahern (50,50) [2]", url,
320				  "XXX http://slurl.com/secondlife/Ahern/50/50 XXX",
321				  "http://slurl.com/secondlife/Ahern/50/50");
322
323		testRegex("Ahern (50)", url,
324				  "XXX http://slurl.com/secondlife/Ahern/50 XXX",
325				  "http://slurl.com/secondlife/Ahern/50");
326
327		testRegex("Ahern", url,
328				  "XXX http://slurl.com/secondlife/Ahern/ XXX",
329				  "http://slurl.com/secondlife/Ahern/");
330
331		testRegex("Ahern SLURL with title", url,
332				  "XXX http://slurl.com/secondlife/Ahern/50/50/50/?title=YOUR%20TITLE%20HERE! XXX",
333				  "http://slurl.com/secondlife/Ahern/50/50/50/?title=YOUR%20TITLE%20HERE!");
334
335		testRegex("Ahern SLURL with msg", url,
336				  "XXX http://slurl.com/secondlife/Ahern/50/50/50/?msg=Your%20text%20here. XXX",
337				  "http://slurl.com/secondlife/Ahern/50/50/50/?msg=Your%20text%20here.");
338
339		// DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat
340		testRegex("SLURL with brackets", url,
341				  "XXX http://slurl.com/secondlife/Burning%20Life%20(Hyper)/27/210/30 XXX",
342				  "http://slurl.com/secondlife/Burning%20Life%20(Hyper)/27/210/30");
343
344		// DEV-35459: SLURLs and teleport Links not parsed properly
345		testRegex("SLURL with quote", url,
346				  "XXX http://slurl.com/secondlife/A'ksha%20Oasis/41/166/701 XXX",
347				  "http://slurl.com/secondlife/A%27ksha%20Oasis/41/166/701");
348	}
349
350	template<> template<>
351	void object::test<4>()
352	{
353		//
354		// test LLUrlEntryAgent - secondlife://app/agent Urls
355		//
356		LLUrlEntryAgent url;
357
358		testRegex("Invalid Agent Url", url,
359				  "secondlife:///app/agent/0e346d8b-4433-4d66-XXXX-fd37083abc4c/about",
360				  "");
361
362		testRegex("Agent Url ", url,
363				  "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about",
364				  "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
365
366		testRegex("Agent Url in text", url,
367				  "XXX secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about XXX",
368				  "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
369
370		testRegex("Agent Url multicase", url,
371				  "XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About XXX",
372				  "secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/About");
373
374		testRegex("Agent Url alternate command", url,
375				  "XXX secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar",
376				  "secondlife:///App/AGENT/0E346D8B-4433-4d66-a6b0-fd37083abc4c/foobar");
377
378		testRegex("Standalone Agent Url ", url,
379				  "x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about",
380				  "x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");		
381
382		testRegex("Standalone Agent Url Multicase with Text", url,
383				  "M x-grid-location-info://lincoln.lindenlab.com/app/AGENT/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about M",
384				  "x-grid-location-info://lincoln.lindenlab.com/app/AGENT/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");		
385	}
386
387	template<> template<>
388	void object::test<5>()
389	{
390		//
391		// test LLUrlEntryGroup - secondlife://app/group Urls
392		//
393		LLUrlEntryGroup url;
394
395		testRegex("Invalid Group Url", url,
396				  "secondlife:///app/group/00005ff3-4044-c79f-XXXX-fb28ae0df991/about",
397				  "");
398
399		testRegex("Group Url ", url,
400				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about",
401				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about");
402
403		testRegex("Group Url ", url,
404				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect",
405				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect");
406
407		testRegex("Group Url in text", url,
408				  "XXX secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about XXX",
409				  "secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about");
410
411		testRegex("Group Url multicase", url,
412				  "XXX secondlife:///APP/Group/00005FF3-4044-c79f-9de8-fb28ae0df991/About XXX",
413				  "secondlife:///APP/Group/00005FF3-4044-c79f-9de8-fb28ae0df991/About");
414		
415		testRegex("Standalone Group Url ", url,
416				  "x-grid-location-info://lincoln.lindenlab.com/app/group/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about",
417				  "x-grid-location-info://lincoln.lindenlab.com/app/group/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");		
418		
419		testRegex("Standalone Group Url Multicase ith Text", url,
420				  "M x-grid-location-info://lincoln.lindenlab.com/app/GROUP/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about M",
421				  "x-grid-location-info://lincoln.lindenlab.com/app/GROUP/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");		
422		
423	}
424
425	template<> template<>
426	void object::test<6>()
427	{
428		//
429		// test LLUrlEntryPlace - secondlife://<location> URLs
430		//
431		LLUrlEntryPlace url;
432
433		testRegex("no valid slurl [1]", url,
434				  "secondlife://Ahern/FOO/50/",
435				  "");
436
437		testRegex("Ahern (50,50,50) [1]", url,
438				  "secondlife://Ahern/50/50/50/",
439				  "secondlife://Ahern/50/50/50/");
440
441		testRegex("Ahern (50,50,50) [2]", url,
442				  "XXX secondlife://Ahern/50/50/50/ XXX",
443				  "secondlife://Ahern/50/50/50/");
444
445		testRegex("Ahern (50,50,50) [3]", url,
446				  "XXX secondlife://Ahern/50/50/50 XXX",
447				  "secondlife://Ahern/50/50/50");
448
449		testRegex("Ahern (50,50,50) multicase", url,
450				  "XXX SecondLife://Ahern/50/50/50/ XXX",
451				  "SecondLife://Ahern/50/50/50/");
452
453		testRegex("Ahern (50,50) [1]", url,
454				  "XXX secondlife://Ahern/50/50/ XXX",
455				  "secondlife://Ahern/50/50/");
456
457		testRegex("Ahern (50,50) [2]", url,
458				  "XXX secondlife://Ahern/50/50 XXX",
459				  "secondlife://Ahern/50/50");
460
461		// DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat
462		testRegex("SLURL with brackets", url,
463				  "XXX secondlife://Burning%20Life%20(Hyper)/27/210/30 XXX",
464				  "secondlife://Burning%20Life%20(Hyper)/27/210/30");
465
466		// DEV-35459: SLURLs and teleport Links not parsed properly
467		testRegex("SLURL with quote", url,
468				  "XXX secondlife://A'ksha%20Oasis/41/166/701 XXX",
469			          "secondlife://A%27ksha%20Oasis/41/166/701");
470		
471		testRegex("Standalone All Hands (50,50) [2] with text", url,
472				  "XXX x-grid-location-info://lincoln.lindenlab.com/region/All%20Hands/50/50/50 XXX",
473				  "x-grid-location-info://lincoln.lindenlab.com/region/All%20Hands/50/50/50");		
474	}
475
476	template<> template<>
477	void object::test<7>()
478	{
479		//
480		// test LLUrlEntryParcel - secondlife://app/parcel Urls
481		//
482		LLUrlEntryParcel url;
483
484		testRegex("Invalid Classified Url", url,
485				  "secondlife:///app/parcel/0000060e-4b39-e00b-XXXX-d98b1934e3a8/about",
486				  "");
487
488		testRegex("Classified Url ", url,
489				  "secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about",
490				  "secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about");
491
492		testRegex("Classified Url in text", url,
493				  "XXX secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about XXX",
494				  "secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about");
495
496		testRegex("Classified Url multicase", url,
497				  "XXX secondlife:///APP/Parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/About XXX",
498				  "secondlife:///APP/Parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/About");
499	}
500	template<> template<>
501	void object::test<8>()
502	{
503		//
504		// test LLUrlEntryTeleport - secondlife://app/teleport URLs
505		//
506		LLUrlEntryTeleport url;
507
508		testRegex("no valid teleport [1]", url,
509				  "http://slurl.com/secondlife/Ahern/50/50/50/",
510				  "");
511
512		testRegex("no valid teleport [2]", url,
513				  "secondlife:///app/teleport/",
514				  "");
515
516		testRegex("no valid teleport [3]", url,
517				  "second-life:///app/teleport/Ahern/50/50/50/",
518				  "");
519
520		testRegex("no valid teleport [3]", url,
521				  "hhtp://slurl.com/secondlife/Ahern/50/FOO/50/",
522				  "");
523
524		testRegex("Ahern (50,50,50) [1]", url,
525				  "secondlife:///app/teleport/Ahern/50/50/50/",
526				  "secondlife:///app/teleport/Ahern/50/50/50/");
527
528		testRegex("Ahern (50,50,50) [2]", url,
529				  "XXX secondlife:///app/teleport/Ahern/50/50/50/ XXX",
530				  "secondlife:///app/teleport/Ahern/50/50/50/");
531
532		testRegex("Ahern (50,50,50) [3]", url,
533				  "XXX secondlife:///app/teleport/Ahern/50/50/50 XXX",
534				  "secondlife:///app/teleport/Ahern/50/50/50");
535
536		testRegex("Ahern (50,50,50) multicase", url,
537				  "XXX secondlife:///app/teleport/Ahern/50/50/50/ XXX",
538				  "secondlife:///app/teleport/Ahern/50/50/50/");
539
540		testRegex("Ahern (50,50) [1]", url,
541				  "XXX secondlife:///app/teleport/Ahern/50/50/ XXX",
542				  "secondlife:///app/teleport/Ahern/50/50/");
543
544		testRegex("Ahern (50,50) [2]", url,
545				  "XXX secondlife:///app/teleport/Ahern/50/50 XXX",
546				  "secondlife:///app/teleport/Ahern/50/50");
547
548		testRegex("Ahern (50)", url,
549				  "XXX secondlife:///app/teleport/Ahern/50 XXX",
550				  "secondlife:///app/teleport/Ahern/50");
551
552		testRegex("Ahern", url,
553				  "XXX secondlife:///app/teleport/Ahern/ XXX",
554				  "secondlife:///app/teleport/Ahern/");
555
556		testRegex("Ahern teleport with title", url,
557				  "XXX secondlife:///app/teleport/Ahern/50/50/50/?title=YOUR%20TITLE%20HERE! XXX",
558				  "secondlife:///app/teleport/Ahern/50/50/50/?title=YOUR%20TITLE%20HERE!");
559
560		testRegex("Ahern teleport with msg", url,
561				  "XXX secondlife:///app/teleport/Ahern/50/50/50/?msg=Your%20text%20here. XXX",
562				  "secondlife:///app/teleport/Ahern/50/50/50/?msg=Your%20text%20here.");
563
564		// DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat
565		testRegex("Teleport with brackets", url,
566				  "XXX secondlife:///app/teleport/Burning%20Life%20(Hyper)/27/210/30 XXX",
567				  "secondlife:///app/teleport/Burning%20Life%20(Hyper)/27/210/30");
568
569		// DEV-35459: SLURLs and teleport Links not parsed properly
570		testRegex("Teleport url with quote", url,
571				  "XXX secondlife:///app/teleport/A'ksha%20Oasis/41/166/701 XXX",
572				  "secondlife:///app/teleport/A%27ksha%20Oasis/41/166/701");
573		
574		testRegex("Standalone All Hands", url,
575				  "XXX x-grid-location-info://lincoln.lindenlab.com/app/teleport/All%20Hands/50/50/50 XXX",
576				  "x-grid-location-info://lincoln.lindenlab.com/app/teleport/All%20Hands/50/50/50");		
577	}
578
579	template<> template<>
580	void object::test<9>()
581	{
582		//
583		// test LLUrlEntrySL - general secondlife:// URLs
584		//
585		LLUrlEntrySL url;
586
587		testRegex("no valid slapp [1]", url,
588				  "http:///app/",
589				  "");
590
591		testRegex("valid slapp [1]", url,
592				  "secondlife:///app/",
593				  "secondlife:///app/");
594
595		testRegex("valid slapp [2]", url,
596				  "secondlife:///app/teleport/Ahern/50/50/50/",
597				  "secondlife:///app/teleport/Ahern/50/50/50/");
598
599		testRegex("valid slapp [3]", url,
600				  "secondlife:///app/foo",
601				  "secondlife:///app/foo");
602
603		testRegex("valid slapp [4]", url,
604				  "secondlife:///APP/foo?title=Hi%20There",
605				  "secondlife:///APP/foo?title=Hi%20There");
606
607		testRegex("valid slapp [5]", url,
608				  "secondlife://host/app/",
609				  "secondlife://host/app/");
610
611		testRegex("valid slapp [6]", url,
612				  "secondlife://host:8080/foo/bar",
613				  "secondlife://host:8080/foo/bar");
614	}
615
616	template<> template<>
617	void object::test<10>()
618	{
619		//
620		// test LLUrlEntrySLLabel - general secondlife:// URLs with labels
621		//
622		LLUrlEntrySLLabel url;
623
624		testRegex("invalid wiki url [1]", url,
625				  "[secondlife:///app/]",
626				  "");
627
628		testRegex("invalid wiki url [2]", url,
629				  "[secondlife:///app/",
630				  "");
631
632		testRegex("invalid wiki url [3]", url,
633				  "[secondlife:///app/ Label",
634				  "");
635
636		testRegex("agent slurl with label (spaces)", url,
637				  "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about  Text]",
638				  "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
639
640		testRegex("agent slurl with label (tabs)", url,
641				  "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about\t Text]",
642				  "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
643
644		testRegex("agent slurl with label", url,
645				  "[secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about FirstName LastName]",
646				  "secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about");
647
648		testRegex("teleport slurl with label", url,
649				  "XXX [secondlife:///app/teleport/Ahern/50/50/50/ Teleport to Ahern] YYY",
650				  "secondlife:///app/teleport/Ahern/50/50/50/");
651	}
652
653	template<> template<>
654	void object::test<11>()
655	{
656		//
657		// test LLUrlEntryHTTPNoProtocol - general URLs without a protocol
658		//
659		LLUrlEntryHTTPNoProtocol url;
660
661		testRegex("naked .com URL", url,
662				  "see google.com",
663				  "http://google.com");
664
665		testRegex("naked .org URL", url,
666				  "see en.wikipedia.org for details",
667				  "http://en.wikipedia.org");
668
669		testRegex("naked .net URL", url,
670				  "example.net",
671				  "http://example.net");
672
673		testRegex("naked .edu URL (2 instances)", url,
674				  "MIT web site is at web.mit.edu and also www.mit.edu",
675				  "http://web.mit.edu");
676
677		testRegex("don't match e-mail addresses", url,
678				  "test@lindenlab.com",
679				  "");
680
681		testRegex(".com URL with path", url,
682				  "see secondlife.com/status for grid status",
683				  "http://secondlife.com/status");
684
685		testRegex(".com URL with port", url,
686				  "secondlife.com:80",
687				  "http://secondlife.com:80");
688
689		testRegex(".com URL with port and path", url,
690				  "see secondlife.com:80/status",
691				  "http://secondlife.com:80/status");
692
693		testRegex("www.*.com URL with port and path", url,
694				  "see www.secondlife.com:80/status",
695				  "http://www.secondlife.com:80/status");
696
697		testRegex("invalid .com URL [1]", url,
698				  "..com",
699				  "");
700
701		testRegex("invalid .com URL [2]", url,
702				  "you.come",
703				  "");
704
705		testRegex("invalid .com URL [3]", url,
706				  "recommended",
707				  "");
708
709		testRegex("invalid .edu URL", url,
710				  "hi there scheduled maitenance has begun",
711				  "");
712
713		testRegex("invalid .net URL", url,
714				  "foo.netty",
715				  "");
716
717		testRegex("XML tags around URL [1]", url,
718				  "<foo>secondlife.com</foo>",
719				  "http://secondlife.com");
720
721		testRegex("XML tags around URL [2]", url,
722				  "<foo>secondlife.com/status?bar=1</foo>",
723				  "http://secondlife.com/status?bar=1");
724	}
725
726	template<> template<>
727	void object::test<12>()
728	{
729		//
730		// test LLUrlEntryNoLink - turn off hyperlinking
731		//
732		LLUrlEntryNoLink url;
733
734		testRegex("<nolink> [1]", url,
735				  "<nolink>google.com</nolink>",
736				  "google.com");
737
738		testRegex("<nolink> [2]", url,
739				  "<nolink>google.com",
740				  "");
741
742		testRegex("<nolink> [3]", url,
743				  "google.com</nolink>",
744				  "");
745
746		testRegex("<nolink> [4]", url,
747				  "<nolink>Hello World</nolink>",
748				  "Hello World");
749
750		testRegex("<nolink> [5]", url,
751				  "<nolink>My Object</nolink>",
752				  "My Object");
753	}
754
755	template<> template<>
756	void object::test<13>()
757	{
758		//
759		// test LLUrlEntryRegion - secondlife:///app/region/<location> URLs
760		//
761		LLUrlEntryRegion url;
762
763		// Regex tests.
764		testRegex("no valid region", url,
765				  "secondlife:///app/region/",
766				  "");
767
768		testRegex("invalid coords", url,
769				  "secondlife:///app/region/Korea2/a/b/c",
770				  "secondlife:///app/region/Korea2/"); // don't count invalid coords
771
772		testRegex("Ahern (50,50,50) [1]", url,
773				  "secondlife:///app/region/Ahern/50/50/50/",
774				  "secondlife:///app/region/Ahern/50/50/50/");
775
776		testRegex("Ahern (50,50,50) [2]", url,
777				  "XXX secondlife:///app/region/Ahern/50/50/50/ XXX",
778				  "secondlife:///app/region/Ahern/50/50/50/");
779
780		testRegex("Ahern (50,50,50) [3]", url,
781				  "XXX secondlife:///app/region/Ahern/50/50/50 XXX",
782				  "secondlife:///app/region/Ahern/50/50/50");
783
784		testRegex("Ahern (50,50,50) multicase", url,
785				  "XXX secondlife:///app/region/Ahern/50/50/50/ XXX",
786				  "secondlife:///app/region/Ahern/50/50/50/");
787
788		testRegex("Ahern (50,50) [1]", url,
789				  "XXX secondlife:///app/region/Ahern/50/50/ XXX",
790				  "secondlife:///app/region/Ahern/50/50/");
791
792		testRegex("Ahern (50,50) [2]", url,
793				  "XXX secondlife:///app/region/Ahern/50/50 XXX",
794				  "secondlife:///app/region/Ahern/50/50");
795
796		// DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat
797		testRegex("Region with brackets", url,
798				  "XXX secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30 XXX",
799				  "secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30");
800
801		// DEV-35459: SLURLs and teleport Links not parsed properly
802		testRegex("Region with quote", url,
803				  "XXX secondlife:///app/region/A'ksha%20Oasis/41/166/701 XXX",
804			          "secondlife:///app/region/A%27ksha%20Oasis/41/166/701");
805
806		// Rendering tests.
807		testLabel("Render /app/region/Ahern/50/50/50/", url,
808			"secondlife:///app/region/Ahern/50/50/50/",
809			"Ahern (50,50,50)");
810
811		testLabel("Render /app/region/Ahern/50/50/50", url,
812			"secondlife:///app/region/Ahern/50/50/50",
813			"Ahern (50,50,50)");
814
815		testLabel("Render /app/region/Ahern/50/50/", url,
816			"secondlife:///app/region/Ahern/50/50/",
817			"Ahern (50,50)");
818
819		testLabel("Render /app/region/Ahern/50/50", url,
820			"secondlife:///app/region/Ahern/50/50",
821			"Ahern (50,50)");
822
823		testLabel("Render /app/region/Ahern/50/", url,
824			"secondlife:///app/region/Ahern/50/",
825			"Ahern (50)");
826
827		testLabel("Render /app/region/Ahern/50", url,
828			"secondlife:///app/region/Ahern/50",
829			"Ahern (50)");
830
831		testLabel("Render /app/region/Ahern/", url,
832			"secondlife:///app/region/Ahern/",
833			"Ahern");
834
835		testLabel("Render /app/region/Ahern/ within context", url,
836			"XXX secondlife:///app/region/Ahern/ XXX",
837			"Ahern");
838
839		testLabel("Render /app/region/Ahern", url,
840			"secondlife:///app/region/Ahern",
841			"Ahern");
842
843		testLabel("Render /app/region/Ahern within context", url,
844			"XXX secondlife:///app/region/Ahern XXX",
845			"Ahern");
846
847		testLabel("Render /app/region/Product%20Engine/", url,
848			"secondlife:///app/region/Product%20Engine/",
849			"Product Engine");
850
851		testLabel("Render /app/region/Product%20Engine", url,
852			"secondlife:///app/region/Product%20Engine",
853			"Product Engine");
854
855		// Location parsing texts.
856		testLocation("Location /app/region/Ahern/50/50/50/", url,
857			"secondlife:///app/region/Ahern/50/50/50/",
858			"Ahern");
859
860		testLocation("Location /app/region/Product%20Engine", url,
861			"secondlife:///app/region/Product%20Engine",
862			"Product Engine");
863	}
864}