@@ -284,4 +284,281 @@ public function testStudly()
284284 $ this ->assertSame ('HelloWorld ' , StrCache::studly ('hello world ' ));
285285 $ this ->assertSame ('Hello-World ' , StrCache::studly ('hello world ' , '- ' ));
286286 }
287+
288+ /**
289+ * @param mixed $validUrl
290+ */
291+ #[\PHPUnit \Framework \Attributes \DataProvider('validUrls ' )]
292+ public function testValidUrls ($ url )
293+ {
294+ $ this ->assertTrue (Str::isUrl ($ url ));
295+ }
296+
297+ /**
298+ * @param mixed $invalidUrl
299+ */
300+ #[\PHPUnit \Framework \Attributes \DataProvider('invalidUrls ' )]
301+ public function testInvalidUrls ($ url )
302+ {
303+ $ this ->assertFalse (Str::isUrl ($ url ));
304+ }
305+
306+ public static function validUrls ()
307+ {
308+ return [
309+ ['aaa://fully.qualified.domain/path ' ],
310+ ['aaas://fully.qualified.domain/path ' ],
311+ ['about://fully.qualified.domain/path ' ],
312+ ['acap://fully.qualified.domain/path ' ],
313+ ['acct://fully.qualified.domain/path ' ],
314+ ['acr://fully.qualified.domain/path ' ],
315+ ['adiumxtra://fully.qualified.domain/path ' ],
316+ ['afp://fully.qualified.domain/path ' ],
317+ ['afs://fully.qualified.domain/path ' ],
318+ ['aim://fully.qualified.domain/path ' ],
319+ ['apt://fully.qualified.domain/path ' ],
320+ ['attachment://fully.qualified.domain/path ' ],
321+ ['aw://fully.qualified.domain/path ' ],
322+ ['barion://fully.qualified.domain/path ' ],
323+ ['beshare://fully.qualified.domain/path ' ],
324+ ['bitcoin://fully.qualified.domain/path ' ],
325+ ['blob://fully.qualified.domain/path ' ],
326+ ['bolo://fully.qualified.domain/path ' ],
327+ ['callto://fully.qualified.domain/path ' ],
328+ ['cap://fully.qualified.domain/path ' ],
329+ ['chrome://fully.qualified.domain/path ' ],
330+ ['chrome-extension://fully.qualified.domain/path ' ],
331+ ['cid://fully.qualified.domain/path ' ],
332+ ['coap://fully.qualified.domain/path ' ],
333+ ['coaps://fully.qualified.domain/path ' ],
334+ ['com-eventbrite-attendee://fully.qualified.domain/path ' ],
335+ ['content://fully.qualified.domain/path ' ],
336+ ['crid://fully.qualified.domain/path ' ],
337+ ['cvs://fully.qualified.domain/path ' ],
338+ ['data://fully.qualified.domain/path ' ],
339+ ['dav://fully.qualified.domain/path ' ],
340+ ['dict://fully.qualified.domain/path ' ],
341+ ['dlna-playcontainer://fully.qualified.domain/path ' ],
342+ ['dlna-playsingle://fully.qualified.domain/path ' ],
343+ ['dns://fully.qualified.domain/path ' ],
344+ ['dntp://fully.qualified.domain/path ' ],
345+ ['dtn://fully.qualified.domain/path ' ],
346+ ['dvb://fully.qualified.domain/path ' ],
347+ ['ed2k://fully.qualified.domain/path ' ],
348+ ['example://fully.qualified.domain/path ' ],
349+ ['facetime://fully.qualified.domain/path ' ],
350+ ['fax://fully.qualified.domain/path ' ],
351+ ['feed://fully.qualified.domain/path ' ],
352+ ['feedready://fully.qualified.domain/path ' ],
353+ ['file://fully.qualified.domain/path ' ],
354+ ['filesystem://fully.qualified.domain/path ' ],
355+ ['finger://fully.qualified.domain/path ' ],
356+ ['fish://fully.qualified.domain/path ' ],
357+ ['ftp://fully.qualified.domain/path ' ],
358+ ['geo://fully.qualified.domain/path ' ],
359+ ['gg://fully.qualified.domain/path ' ],
360+ ['git://fully.qualified.domain/path ' ],
361+ ['gizmoproject://fully.qualified.domain/path ' ],
362+ ['go://fully.qualified.domain/path ' ],
363+ ['gopher://fully.qualified.domain/path ' ],
364+ ['gtalk://fully.qualified.domain/path ' ],
365+ ['h323://fully.qualified.domain/path ' ],
366+ ['ham://fully.qualified.domain/path ' ],
367+ ['hcp://fully.qualified.domain/path ' ],
368+ ['http://fully.qualified.domain/path ' ],
369+ ['https://fully.qualified.domain/path ' ],
370+ ['iax://fully.qualified.domain/path ' ],
371+ ['icap://fully.qualified.domain/path ' ],
372+ ['icon://fully.qualified.domain/path ' ],
373+ ['im://fully.qualified.domain/path ' ],
374+ ['imap://fully.qualified.domain/path ' ],
375+ ['info://fully.qualified.domain/path ' ],
376+ ['iotdisco://fully.qualified.domain/path ' ],
377+ ['ipn://fully.qualified.domain/path ' ],
378+ ['ipp://fully.qualified.domain/path ' ],
379+ ['ipps://fully.qualified.domain/path ' ],
380+ ['irc://fully.qualified.domain/path ' ],
381+ ['irc6://fully.qualified.domain/path ' ],
382+ ['ircs://fully.qualified.domain/path ' ],
383+ ['iris://fully.qualified.domain/path ' ],
384+ ['iris.beep://fully.qualified.domain/path ' ],
385+ ['iris.lwz://fully.qualified.domain/path ' ],
386+ ['iris.xpc://fully.qualified.domain/path ' ],
387+ ['iris.xpcs://fully.qualified.domain/path ' ],
388+ ['itms://fully.qualified.domain/path ' ],
389+ ['jabber://fully.qualified.domain/path ' ],
390+ ['jar://fully.qualified.domain/path ' ],
391+ ['jms://fully.qualified.domain/path ' ],
392+ ['keyparc://fully.qualified.domain/path ' ],
393+ ['lastfm://fully.qualified.domain/path ' ],
394+ ['ldap://fully.qualified.domain/path ' ],
395+ ['ldaps://fully.qualified.domain/path ' ],
396+ ['magnet://fully.qualified.domain/path ' ],
397+ ['mailserver://fully.qualified.domain/path ' ],
398+ ['mailto://fully.qualified.domain/path ' ],
399+ ['maps://fully.qualified.domain/path ' ],
400+ ['market://fully.qualified.domain/path ' ],
401+ ['message://fully.qualified.domain/path ' ],
402+ ['mid://fully.qualified.domain/path ' ],
403+ ['mms://fully.qualified.domain/path ' ],
404+ ['modem://fully.qualified.domain/path ' ],
405+ ['ms-help://fully.qualified.domain/path ' ],
406+ ['ms-settings://fully.qualified.domain/path ' ],
407+ ['ms-settings-airplanemode://fully.qualified.domain/path ' ],
408+ ['ms-settings-bluetooth://fully.qualified.domain/path ' ],
409+ ['ms-settings-camera://fully.qualified.domain/path ' ],
410+ ['ms-settings-cellular://fully.qualified.domain/path ' ],
411+ ['ms-settings-cloudstorage://fully.qualified.domain/path ' ],
412+ ['ms-settings-emailandaccounts://fully.qualified.domain/path ' ],
413+ ['ms-settings-language://fully.qualified.domain/path ' ],
414+ ['ms-settings-location://fully.qualified.domain/path ' ],
415+ ['ms-settings-lock://fully.qualified.domain/path ' ],
416+ ['ms-settings-nfctransactions://fully.qualified.domain/path ' ],
417+ ['ms-settings-notifications://fully.qualified.domain/path ' ],
418+ ['ms-settings-power://fully.qualified.domain/path ' ],
419+ ['ms-settings-privacy://fully.qualified.domain/path ' ],
420+ ['ms-settings-proximity://fully.qualified.domain/path ' ],
421+ ['ms-settings-screenrotation://fully.qualified.domain/path ' ],
422+ ['ms-settings-wifi://fully.qualified.domain/path ' ],
423+ ['ms-settings-workplace://fully.qualified.domain/path ' ],
424+ ['msnim://fully.qualified.domain/path ' ],
425+ ['msrp://fully.qualified.domain/path ' ],
426+ ['msrps://fully.qualified.domain/path ' ],
427+ ['mtqp://fully.qualified.domain/path ' ],
428+ ['mumble://fully.qualified.domain/path ' ],
429+ ['mupdate://fully.qualified.domain/path ' ],
430+ ['mvn://fully.qualified.domain/path ' ],
431+ ['news://fully.qualified.domain/path ' ],
432+ ['nfs://fully.qualified.domain/path ' ],
433+ ['ni://fully.qualified.domain/path ' ],
434+ ['nih://fully.qualified.domain/path ' ],
435+ ['nntp://fully.qualified.domain/path ' ],
436+ ['notes://fully.qualified.domain/path ' ],
437+ ['oid://fully.qualified.domain/path ' ],
438+ ['opaquelocktoken://fully.qualified.domain/path ' ],
439+ ['pack://fully.qualified.domain/path ' ],
440+ ['palm://fully.qualified.domain/path ' ],
441+ ['paparazzi://fully.qualified.domain/path ' ],
442+ ['pkcs11://fully.qualified.domain/path ' ],
443+ ['platform://fully.qualified.domain/path ' ],
444+ ['pop://fully.qualified.domain/path ' ],
445+ ['pres://fully.qualified.domain/path ' ],
446+ ['prospero://fully.qualified.domain/path ' ],
447+ ['proxy://fully.qualified.domain/path ' ],
448+ ['psyc://fully.qualified.domain/path ' ],
449+ ['query://fully.qualified.domain/path ' ],
450+ ['redis://fully.qualified.domain/path ' ],
451+ ['rediss://fully.qualified.domain/path ' ],
452+ ['reload://fully.qualified.domain/path ' ],
453+ ['res://fully.qualified.domain/path ' ],
454+ ['resource://fully.qualified.domain/path ' ],
455+ ['rmi://fully.qualified.domain/path ' ],
456+ ['rsync://fully.qualified.domain/path ' ],
457+ ['rtmfp://fully.qualified.domain/path ' ],
458+ ['rtmp://fully.qualified.domain/path ' ],
459+ ['rtsp://fully.qualified.domain/path ' ],
460+ ['rtsps://fully.qualified.domain/path ' ],
461+ ['rtspu://fully.qualified.domain/path ' ],
462+ ['s3://fully.qualified.domain/path ' ],
463+ ['secondlife://fully.qualified.domain/path ' ],
464+ ['service://fully.qualified.domain/path ' ],
465+ ['session://fully.qualified.domain/path ' ],
466+ ['sftp://fully.qualified.domain/path ' ],
467+ ['sgn://fully.qualified.domain/path ' ],
468+ ['shttp://fully.qualified.domain/path ' ],
469+ ['sieve://fully.qualified.domain/path ' ],
470+ ['sip://fully.qualified.domain/path ' ],
471+ ['sips://fully.qualified.domain/path ' ],
472+ ['skype://fully.qualified.domain/path ' ],
473+ ['smb://fully.qualified.domain/path ' ],
474+ ['sms://fully.qualified.domain/path ' ],
475+ ['smtp://fully.qualified.domain/path ' ],
476+ ['snews://fully.qualified.domain/path ' ],
477+ ['snmp://fully.qualified.domain/path ' ],
478+ ['soap.beep://fully.qualified.domain/path ' ],
479+ ['soap.beeps://fully.qualified.domain/path ' ],
480+ ['soldat://fully.qualified.domain/path ' ],
481+ ['spotify://fully.qualified.domain/path ' ],
482+ ['ssh://fully.qualified.domain/path ' ],
483+ ['steam://fully.qualified.domain/path ' ],
484+ ['stun://fully.qualified.domain/path ' ],
485+ ['stuns://fully.qualified.domain/path ' ],
486+ ['submit://fully.qualified.domain/path ' ],
487+ ['svn://fully.qualified.domain/path ' ],
488+ ['tag://fully.qualified.domain/path ' ],
489+ ['teamspeak://fully.qualified.domain/path ' ],
490+ ['tel://fully.qualified.domain/path ' ],
491+ ['teliaeid://fully.qualified.domain/path ' ],
492+ ['telnet://fully.qualified.domain/path ' ],
493+ ['tftp://fully.qualified.domain/path ' ],
494+ ['things://fully.qualified.domain/path ' ],
495+ ['thismessage://fully.qualified.domain/path ' ],
496+ ['tip://fully.qualified.domain/path ' ],
497+ ['tn3270://fully.qualified.domain/path ' ],
498+ ['turn://fully.qualified.domain/path ' ],
499+ ['turns://fully.qualified.domain/path ' ],
500+ ['tv://fully.qualified.domain/path ' ],
501+ ['udp://fully.qualified.domain/path ' ],
502+ ['unreal://fully.qualified.domain/path ' ],
503+ ['urn://fully.qualified.domain/path ' ],
504+ ['ut2004://fully.qualified.domain/path ' ],
505+ ['vemmi://fully.qualified.domain/path ' ],
506+ ['ventrilo://fully.qualified.domain/path ' ],
507+ ['videotex://fully.qualified.domain/path ' ],
508+ ['view-source://fully.qualified.domain/path ' ],
509+ ['wais://fully.qualified.domain/path ' ],
510+ ['webcal://fully.qualified.domain/path ' ],
511+ ['ws://fully.qualified.domain/path ' ],
512+ ['wss://fully.qualified.domain/path ' ],
513+ ['wtai://fully.qualified.domain/path ' ],
514+ ['wyciwyg://fully.qualified.domain/path ' ],
515+ ['xcon://fully.qualified.domain/path ' ],
516+ ['xcon-userid://fully.qualified.domain/path ' ],
517+ ['xfire://fully.qualified.domain/path ' ],
518+ ['xmlrpc.beep://fully.qualified.domain/path ' ],
519+ ['xmlrpc.beeps://fully.qualified.domain/path ' ],
520+ ['xmpp://fully.qualified.domain/path ' ],
521+ ['xri://fully.qualified.domain/path ' ],
522+ ['ymsgr://fully.qualified.domain/path ' ],
523+ ['z39.50://fully.qualified.domain/path ' ],
524+ ['z39.50r://fully.qualified.domain/path ' ],
525+ ['z39.50s://fully.qualified.domain/path ' ],
526+ ['http://a.pl ' ],
527+ ['http://localhost/url.php ' ],
528+ ['http://local.dev ' ],
529+ ['http://google.com ' ],
530+ ['http://www.google.com ' ],
531+ ['https://google.com ' ],
532+ ['http://illuminate.dev ' ],
533+ ['http://localhost ' ],
534+ ['https://laravel.com/? ' ],
535+ ['http://президент.рф/ ' ],
536+ ['http://스타벅스코리아.com ' ],
537+ ['http://xn--d1abbgf6aiiy.xn--p1ai/ ' ],
538+ ['https://laravel.com? ' ],
539+ ['https://laravel.com?q=1 ' ],
540+ ['https://laravel.com/?q=1 ' ],
541+ ['https://laravel.com# ' ],
542+ ['https://laravel.com#fragment ' ],
543+ ['https://laravel.com/#fragment ' ],
544+ ];
545+ }
546+
547+ public static function invalidUrls ()
548+ {
549+ return [
550+ ['aslsdlks ' ],
551+ ['google.com ' ],
552+ ['://google.com ' ],
553+ ['http ://google.com ' ],
554+ ['http:/google.com ' ],
555+ ['http://goog_le.com ' ],
556+ ['http://google.com::aa ' ],
557+ ['http://google.com:aa ' ],
558+ ['http://127.0.0.1:aa ' ],
559+ ['http://[::1 ' ],
560+ ['foo://bar ' ],
561+ ['javascript://test%0Aalert(321) ' ],
562+ ];
563+ }
287564}
0 commit comments