* Copyright 2001-2012 Strangecode, LLC * * This file is part of The Strangecode Codebase. * * The Strangecode Codebase is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your option) * any later version. * * The Strangecode Codebase is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * The Strangecode Codebase. If not, see . */ /** * PHPUnit test case for codebase/lib/Utilities.inc.php * * The method skeletons below need to be filled in with * real data so that the tests will run correctly. Replace * all EXPECTED_VAL and PARAM strings with real data. * * Created with PHPUnit_Skeleton on 2005-08-09 */ class UtilitiesTest extends PHPUnit_Framework_TestCase { function setUp() { // define('_CLI', true); require dirname(__FILE__) . '/_config.inc.php'; require_once '../lib/Utilities.inc.php'; // $this->Utilities =& new Utilities(PARAM); } function tearDown() { $app =& App::getInstance(); $app->stop(); } function test_hyperlinkTxt() { $urls = [ ' http://www.asdf.com/ ' => ' www.asdf.com ', ' ws://www.asdf.com/ ' => ' ws://www.asdf.com/ ', ' sftp://user@host.tld:22/path/x ' => ' sftp://user@host.tld:22/path/x ', ' www.asdf.com/ ' => ' www.asdf.com ', ' http://asdf/ ' => ' asdf ', ' www.asdf.com/? ' => ' www.asdf.com? ', ' www.asdf.com/?x=y+z ' => ' www.asdf.com/?x=y+z ', ' www.asdf.com/?x=y+ ' => ' www.asdf.com/?x=y+ ', ' www.asdf.com/?x= ' => ' www.asdf.com/?x= ', ' www.asdf.com/?x ' => ' www.asdf.com/?x ', ' www.asdf.com/?❤️=🔥 ' => ' www.asdf.com/?❤️=🔥 ', ' www.asdf.com? ' => ' www.asdf.com? ', ' www.asdf.com! ' => ' www.asdf.com! ', ' www.asdf.com. ' => ' www.asdf.com. ', ' `www.asdf.com` ' => ' `www.asdf.com` ', ' "www.asdf.com" ' => ' "www.asdf.com" ', ' ' => ' <www.asdf.com> ', ' ' => ' <www.asdf.com> ', ' (http://www.asdf.com) ' => ' (www.asdf.com) ', ' (URL: http://www.asdf.com#1) ' => ' (URL: www.asdf.com#1) ', ' Click Here ' => ' Click Here ', ' http://www.example.com/ ' => ' http://www.example.com/ ', ' http://www.example.com/ ' => ' http://www.example.com/ ', ' http://www.example.com/ ' => ' http://www.example.com/ ', ' http://foo.com/blah_blah ' => ' foo.com/blah_blah ', ' http://foo.com/blah_blah/ ' => ' foo.com/blah_blah/ ', ' http://foo.com/blah_blah_(wikipedia) ' => ' foo.com/blah_blah_(wikipedia) ', ' http://foo.com/blah_blah_(wikipedia)_(again) ' => ' foo.com/blah_blah_(wikipedia)_(again) ', ' http://www.example.com/wpstyle/?p=364 ' => ' www.example.com/wpstyle/?p=364 ', ' https://www.example.com/foo/?bar=baz&inga=42&quux ' => ' www.example.com/foo/?bar=baz&inga=42&quux ', ' http://✪df.ws/123 ' => ' ✪df.ws/123 ', ' http://userid:password@example.com:8080 ' => ' userid:password@example.com:8080 ', ' http://userid:password@example.com:8080/ ' => ' userid:password@example.com:8080 ', ' http://userid@example.com ' => ' userid@example.com ', ' http://userid@example.com/ ' => ' userid@example.com ', ' http://userid@example.com:8080 ' => ' userid@example.com:8080 ', ' http://userid@example.com:8080/ ' => ' userid@example.com:8080 ', ' http://userid:password@example.com ' => ' userid:password@example.com ', ' http://userid:password@example.com/ ' => ' userid:password@example.com ', ' http://142.42.1.1/ ' => ' 142.42.1.1 ', ' http://142.42.1.1:8080/ ' => ' 142.42.1.1:8080 ', ' http://➡.ws/䨹 ' => ' ➡.ws/䨹 ', ' http://⌘.ws ' => ' ⌘.ws ', ' http://⌘.ws/ ' => ' ⌘.ws ', ' http://foo.com/blah_(wikipedia)#cite-1 ' => ' foo.com/blah_(wikipedia)#cite-1 ', ' http://foo.com/blah_(wikipedia)_blah#cite-1 ' => ' foo.com/blah_(wikipedia)_blah#cite-1 ', ' http://foo.com/unicode_(✪)_in_parens ' => ' foo.com/unicode_(✪)_in_parens ', ' http://foo.com/(something)?after=parens ' => ' foo.com/(something)?after=parens ', ' http://☺.damowmow.com/ ' => ' ☺.damowmow.com ', ' http://code.google.com/events/#&product=browser ' => ' code.google.com/events/#&product=browser ', ' http://j.mp ' => ' j.mp ', ' ftp://foo.bar/baz ' => ' ftp://foo.bar/baz ', ' http://foo.bar/?q=Test%20URL-encoded%20stuff ' => ' foo.bar/?q=Test%20URL-encoded%20stuff ', ' http://مثال.إختبار ' => ' مثال.إختبار ', ' http://例子.测试 ' => ' 例子.测试 ', ' http://उदाहरण.परीक्षा ' => ' उदाहरण.परीक्षा ', ' http://-.~_!$&\'()*+,;=:%40:80%2f::::::@example.com ' => ' -.~_!$&\'()*+,;=:%40:80%2f::::::@example.com ', ' http://1337.net ' => ' 1337.net ', ' http://a.b-c.de ' => ' a.b-c.de ', ' http://223.255.255.254 ' => ' 223.255.255.254 ', ' http://x and.co OK?' => ' http://x and.co OK?', ' http://foo.bar?q=Spaces should be encoded ' => ' foo.bar?q=Spaces should be encoded ', ' https://github.com/search?utf8=✓&q=gif ' => ' github.com/search?utf8=✓&q=gif ', ' https://github.com/search?q=gif&utf8=* ' => ' github.com/search?q=gif&utf8=* ', ' https://github.com/search?q=gif&utf8=✓ ' => ' github.com/search?q=gif&utf8=✓ ', // These should fail. ' http://x and.co OK?' => ' http://x and.co OK?', ' www. ' => ' www. ', ' www.x ' => ' www.x ', ' http: ' => ' http: ', ' http:// ' => ' http:// ', ' http:x ' => ' http:x ', ' http://x ' => ' http://x ', ' http://x/ ' => ' http://x/ ', ' http:// ?.x.com/ ' => ' http:// ?.x.com/ ', ' http://?.com/ ' => ' http://?.com/ ', ' http://.?.com/ ' => ' http://.?.com/ ', // These are allowed to fuckup due to limitations in our ability to be omnipotent. ' http:// www.x.com/ ' => ' http:// www.x.com ', ' http://www.example.com/ ' => ' www.example.com ', 'Lorem ipsum dolor sit amet sftp://user@host.tld/path, [http://www.example.com/ consetetur] sadipscing elitr, (sed diam) www.example.com! Nonumy http://x.com! Invidunt mailto:asdf@asdf.com ut asdf@asdf.com \'\'\'et dolore\'\'\' magna. Aliquyam:erat, sed://diam //voluptua//. At vero.eos.et {{{ for (var i = Things.length - 1; i >= 0; i--) { Things[i]; } }}} `http://x.com` justo duo doloreshttp://www.not.com!' => 'Lorem ipsum dolor sit amet sftp://user@host.tld/path, [www.example.com consetetur] sadipscing elitr, (sed diam) www.example.com! Nonumy x.com! Invidunt mailto:asdf@asdf.com ut asdf@asdf.com \'\'\'et dolore\'\'\' magna. Aliquyam:erat, sed://diam //voluptua//. At vero.eos.et {{{ for (var i = Things.length - 1; i >= 0; i--) { Things[i]; } }}} `http://x.com` justo duo doloreshttp://www.not.com!', ]; $urls_strict = [ ' http://www.asdf.com/ ' => ' www.asdf.com ', ' ws://www.asdf.com/ ' => ' ws://www.asdf.com/ ', ' sftp://user@host.tld:22/path/x ' => ' sftp://user@host.tld:22/path/x ', ' sip:beer ' => ' sip:beer ', ' http://asdf/ ' => ' asdf ', ' http://www.asdf.com/? ' => ' www.asdf.com/? ', ' http://www.asdf.com/?x=y+z ' => ' www.asdf.com/?x=y+z ', ' http://www.asdf.com/?x=y+ ' => ' www.asdf.com/?x=y+ ', ' http://www.asdf.com/?x= ' => ' www.asdf.com/?x= ', ' http://www.asdf.com/?x ' => ' www.asdf.com/?x ', ' https://www.asdf.com/?❤️=🔥 ' => ' www.asdf.com/?❤️=🔥 ', ' www.asdf.com? ' => ' www.asdf.com? ', ' www.asdf.com/ ' => ' www.asdf.com/ ', ' www.asdf.com/? ' => ' www.asdf.com/? ', ' www.asdf.com/?x=y+z ' => ' www.asdf.com/?x=y+z ', ' www.asdf.com/?x=y+ ' => ' www.asdf.com/?x=y+ ', ' www.asdf.com/?x= ' => ' www.asdf.com/?x= ', ' www.asdf.com/?x ' => ' www.asdf.com/?x ', ' www.asdf.com/?❤️=🔥 ' => ' www.asdf.com/?❤️=🔥 ', ' www.asdf.com! ' => ' www.asdf.com! ', ' www.asdf.com. ' => ' www.asdf.com. ', ' `www.asdf.com` ' => ' `www.asdf.com` ', ' "www.asdf.com" ' => ' "www.asdf.com" ', ' ' => ' ', ' `http://www.asdf.com` ' => ' `http://www.asdf.com` ', ' "http://www.asdf.com" ' => ' "http://www.asdf.com" ', ' ' => ' <www.asdf.com> ', ' (http://www.asdf.com) ' => ' (www.asdf.com) ', ' (URL: http://www.asdf.com#1) ' => ' (URL: www.asdf.com#1) ', ' Click Here ' => ' Click Here ', ' http://www.example.com/ ' => ' http://www.example.com/ ', ' http://www.example.com/ ' => ' http://www.example.com/ ', ' http://www.example.com/ ' => ' http://www.example.com/ ', ' http://foo.com/blah_blah ' => ' foo.com/blah_blah ', ' http://foo.com/blah_blah/ ' => ' foo.com/blah_blah/ ', ' http://foo.com/blah_blah_(wikipedia) ' => ' foo.com/blah_blah_(wikipedia) ', ' http://foo.com/blah_blah_(wikipedia)_(again) ' => ' foo.com/blah_blah_(wikipedia)_(again) ', ' http://www.example.com/wpstyle/?p=364 ' => ' www.example.com/wpstyle/?p=364 ', ' https://www.example.com/foo/?bar=baz&inga=42&quux ' => ' www.example.com/foo/?bar=baz&inga=42&quux ', ' http://✪df.ws/123 ' => ' ✪df.ws/123 ', ' http://userid:password@example.com:8080 ' => ' userid:password@example.com:8080 ', ' http://userid:password@example.com:8080/ ' => ' userid:password@example.com:8080 ', ' http://userid@example.com ' => ' userid@example.com ', ' http://userid@example.com/ ' => ' userid@example.com ', ' http://userid@example.com:8080 ' => ' userid@example.com:8080 ', ' http://userid@example.com:8080/ ' => ' userid@example.com:8080 ', ' http://userid:password@example.com ' => ' userid:password@example.com ', ' http://userid:password@example.com/ ' => ' userid:password@example.com ', ' http://142.42.1.1/ ' => ' 142.42.1.1 ', ' http://142.42.1.1:8080/ ' => ' 142.42.1.1:8080 ', ' http://➡.ws/䨹 ' => ' ➡.ws/䨹 ', ' http://⌘.ws ' => ' ⌘.ws ', ' http://⌘.ws/ ' => ' ⌘.ws ', ' http://foo.com/blah_(wikipedia)#cite-1 ' => ' foo.com/blah_(wikipedia)#cite-1 ', ' http://foo.com/blah_(wikipedia)_blah#cite-1 ' => ' foo.com/blah_(wikipedia)_blah#cite-1 ', ' http://foo.com/unicode_(✪)_in_parens ' => ' foo.com/unicode_(✪)_in_parens ', ' http://foo.com/(something)?after=parens ' => ' foo.com/(something)?after=parens ', ' http://☺.damowmow.com/ ' => ' ☺.damowmow.com ', ' http://code.google.com/events/#&product=browser ' => ' code.google.com/events/#&product=browser ', ' http://j.mp ' => ' j.mp ', ' ftp://foo.bar/baz ' => ' ftp://foo.bar/baz ', ' http://foo.bar/?q=Test%20URL-encoded%20stuff ' => ' foo.bar/?q=Test%20URL-encoded%20stuff ', ' http://مثال.إختبار ' => ' مثال.إختبار ', ' http://例子.测试 ' => ' 例子.测试 ', ' http://उदाहरण.परीक्षा ' => ' उदाहरण.परीक्षा ', ' http://-.~_!$&\'()*+,;=:%40:80%2f::::::@example.com ' => ' -.~_!$&\'()*+,;=:%40:80%2f::::::@example.com ', ' http://1337.net ' => ' 1337.net ', ' http://a.b-c.de ' => ' a.b-c.de ', ' http://223.255.255.254 ' => ' 223.255.255.254 ', ' http://foo.bar?q=Spaces should be encoded ' => ' foo.bar?q=Spaces should be encoded ', ' https://github.com/search?utf8=✓&q=gif ' => ' github.com/search?utf8=✓&q=gif ', ' https://github.com/search?q=gif&utf8=* ' => ' github.com/search?q=gif&utf8=* ', ' https://github.com/search?q=gif&utf8=✓ ' => ' github.com/search?q=gif&utf8=✓ ', // Unusual schemes. ' view-source:https://trac.strangecode.com/x/ticket/2#comment:4 ' => ' view-source:https://trac.strangecode.com/x/ticket/2#comment:4 ', ' mailto:asdf@asdf.com ' => ' mailto:asdf@asdf.com ', ' facetime://+19995551234 ' => ' facetime://+19995551234 ', ' tel:+15552001010 ' => ' tel:+15552001010 ', ' magnet:?xt=urn:ed2k:354B15E68FB8F36D7CD88FF94116CDC1&xt=urn:tree:tiger:7N5OAMRNGMSSEUE3ORHOKWN4WWIQ5X4EBOOTLJY&xt=urn:btih:QHQXPYWMACKDWKP47RRVIV7VOURXFE5Q&xl=10826029&dn=mediawiki-1.15.1.tar.gz&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80%2Fannounce&as=http%3A%2F%2Fdownload.wikimedia.org%2Fmediawiki%2F1.15%2Fmediawiki-1.15.1.tar.gz&xs=http%3A%2F%2Fcache.example.org%2FXRX2PEFXOOEJFRVUCX6HMZMKS5TWG4K5&xs=dchub://example.org ' => ' magnet:?xt=urn:ed2k:354B15E68FB8F36D7CD88FF94116CDC1&xt=urn:tree:tiger:7N5OAMRNGMSSEUE3ORHOKWN4WWIQ5X4EBOOTLJY&xt=urn:btih:QHQXPYWMACKDWKP47RRVIV7VOURXFE5Q&xl=10826029&dn=mediawiki-1.15.1.tar.gz&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80%2Fannounce&as=http%3A%2F%2Fdownload.wikimedia.org%2Fmediawiki%2F1.15%2Fmediawiki-1.15.1.tar.gz&xs=http%3A%2F%2Fcache.example.org%2FXRX2PEFXOOEJFRVUCX6HMZMKS5TWG4K5&xs=dchub://example.org ', ' chrome-extension://71f05c488a96b441ef679b09267ea46c/index.html ' => ' chrome-extension://71f05c488a96b441ef679b09267ea46c/index.html ', // These should fail. ' http://x and.co OK?' => ' http://x and.co OK?', ' www. ' => ' www. ', ' www.x ' => ' www.x ', ' http: ' => ' http: ', ' http:// ' => ' http:// ', ' http:x ' => ' http:x ', ' http://x ' => ' http://x ', ' http://x/ ' => ' http://x/ ', ' http:// www.x.com/ ' => ' http:// www.x.com/ ', ' http://?.com/ ' => ' http://?.com/ ', ' http://.?.com/ ' => ' http://.?.com/ ', // These are allowed to fuckup due to limitations in our ability to be omnipotent. ' http://www.example.com/ ' => ' www.example.com ', ' dummyhttp://www.asdf.com/ ' => ' dummyhttp://www.asdf.com/ ', 'Lorem ipsum dolor sit amet sftp://user@host.tld/path, [http://www.example.com/ consetetur] sadipscing elitr, (sed diam) www.example.com! Nonumy http://x.com! Invidunt mailto:asdf@asdf.com ut asdf@asdf.com \'\'\'et dolore\'\'\' magna. Aliquyam:erat, sed://diam //voluptua//. At vero.eos.et {{{ for (var i = Things.length - 1; i >= 0; i--) { Things[i]; } }}} `http://x.com` justo duo doloreshttp://www.not.com!' => 'Lorem ipsum dolor sit amet sftp://user@host.tld/path, [www.example.com consetetur] sadipscing elitr, (sed diam) www.example.com! Nonumy x.com! Invidunt mailto:asdf@asdf.com ut asdf@asdf.com \'\'\'et dolore\'\'\' magna. Aliquyam:erat, sed://diam //voluptua//. At vero.eos.et {{{ for (var i = Things.length - 1; i >= 0; i--) { Things[i]; } }}} `http://x.com` justo duo doloreshttp://www.not.com!', ]; foreach ($urls as $input => $expected) { $result = hyperlinkTxt($input, false); $this->assertEquals($expected, $result, sprintf('Failed with input: %s', $input)); } foreach ($urls_strict as $input => $expected) { // printf("'%s' => '%s',\n", $input, hyperlinkTxt($input, true)); $result = hyperlinkTxt($input, true); $this->assertEquals($expected, $result, sprintf('Failed with input: %s', $input)); } } function test_fancyTxt() { $strings = [ 'Due to the fires in "Paradise," CA it\'s a bad day.' => '• Due to the fires in “Paradise,” CA it’s a bad day.', 'Simply--"\'check back\' later"--in 6\'3"...' => '• Simply – “‘check back’ later” – in 6\'3"…', '"Double "double \'single\'""--?' => '• "Double “double ‘single’”" – ?', 'Click here....' => '• Click here....', 'If you have any questions please contact the ants\' mailboxes.' => '• If you have any questions please contact the ants’ mailboxes.', 'This URL: "http://例子.卷筒纸/?x=y&1=2#asdf"' => '• This URL: “http://例子.卷筒纸/?x=y&1=2#asdf”', // '\'...\' and "..."' => '• ‘…’ and “…”', // FIXME: this one doesn't work. '\'1...\' and "2..."' => '• ‘1…’ and “2…”', '\'One\'s self...\' and "Twosome"' => '• ‘One’s self…’ and “Twosome”', '"\'Well,\' said I, \'the gentleman at No. 4.\'"' => '• “‘Well,’ said I, ‘the gentleman at No. 4.’”', '"...an office in Leadenhall Street--and--" "O\'Reilly\'s office?" "What!" he roared. "Yes, to-day."* She stood smiling.' => '• “…an office in Leadenhall Street – and – ” “O’Reilly’s office?” “What!” he roared. “Yes, to-day.”* She stood smiling.', ]; foreach ($strings as $input => $expected) { $result = fancyTxt($input, ['/^/', '/^·/'], ['· ', '•']); $this->assertEquals($expected, $result, sprintf('Failed with input: %s', $input)); } } function test_URLSlug() { $strings = [ 'This becomes a slug' => 'this-becomes-a-slug', 'http://例子.卷筒纸/?x=y&1=2#asdf' => 'http-%e4%be%8b%e5%ad%90-%e5%8d%b7%e7%ad%92%e7%ba%b8-x-yand1-2-asdf', 'Ä ä Ö ö Ü ü ß a Æ æ Ø ø Å å' => 'a-a-o-o-u-u-sz-a-ae-ae-o-o-a-a', ' - ' => '', '' => '', ' ' => '', '?' => '', 'a file.JPG' => 'a-file-jpg', '/a/path/file.JPG' => 'a-path-file-jpg', '/a/directory/' => 'a-directory', '/' => '', 'this-is-already-a-slug' => 'this-is-already-a-slug', 'HTML entities ok—or not!' => 'html-entities-ok-or-not', '

tags…

' => 'ltpgttagshelliplt-pgt', 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.' => 'lorem-ipsum-dolor-sit-amet-consetetur-sadipscing-elitr-sed-diam-nonumy-eirmod-tempor-invidunt-ut-labore-et-dolore-magna-aliquyam-erat-sed-diam-voluptua-at-vero-eos-et-accusam-et-justo-duo-dolores-et-ea-rebum-stet-clita-kasd-gubergren-no-sea-takimata-sanctus-est-lorem-ipsum-dolor-sit-amet-lorem-ipsum-dolor-sit-amet-consetetur-sadipscing-elitr-sed-diam-nonumy-eirmod-tempor-invidunt-ut-labore-et-dolore-magna-aliquyam-erat-sed-diam-voluptua-at-vero-eos-et-accusam-et-justo-duo-dolores-et-ea-rebum-stet-clita-kasd-gubergren-no-sea-takimata-sanctus-est-lorem-ipsum-dolor-sit-amet-lorem-ipsum-dolor-sit-amet-consetetur-sadipscing-elitr-sed-diam-nonumy-eirmod-tempor-invidunt-ut-labore-et-dolore-magna-aliquyam-erat-sed-diam-voluptua-at-vero-eos-et-accusam-et-justo-duo-dolores-et-ea-rebum-stet-clita-kasd-gubergren-no-sea-takimata-sanctus-est-lorem-ipsum-dolor-sit-amet', // Binary data. 'xÔ‡-]ɯpı o˜;ǯ)0ñ]àfhH¡Êg+£KˇH ˙n*∆ɇ͘üQÒõ.◊ulÌ≠˘yÁ˜ïu∫›¢>kƒ∑æì+¯∞˛ ‘E¬±Âh”U÷%>≈fifi≤1' => 'xodagger-emacrp%c4%b1-otildecmacr0nafhhiexcleg-poundk%cb%87h-nedaggeritildeuqoo-lozulineyatildeiuintcentgtkfnofsumaei-macrinfin-enotplusmnahudividegtasymp%ef%ac%81%ef%ac%81le1', '-- repeated - characters -- so---extra - - - look-out!' => 'repeated-characters-so-extra-look-out', 'Nesthäkchen\'s Teenage Years' => 'nesthakchens-teenage-years', 'Ἀχαρνεῖς Akharneîs' => '%e1%bc%88chialpharhonuepsilon%e1%bf%96sigmaf-akharneis', 'Антон Павлович Чехов' => '%d0%90%d0%bd%d1%82%d0%be%d0%bd-%d0%9f%d0%b0%d0%b2%d0%bb%d0%be%d0%b2%d0%b8%d1%87-%d0%a7%d0%b5%d1%85%d0%be%d0%b2', 'Demain dès l\'aube' => 'demain-des-laube', 'Demain dès l’aube' => 'demain-des-laube', ]; foreach ($strings as $input => $expected) { // printf("%s\n", URLSlug($input)); $result = URLSlug($input); $this->assertEquals($expected, $result, sprintf('Failed with input: %s', $input)); } } }