index.js 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080
  1. 'use strict';
  2. /*
  3. * Copyright Joyent, Inc. and other Node contributors.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a
  6. * copy of this software and associated documentation files (the
  7. * "Software"), to deal in the Software without restriction, including
  8. * without limitation the rights to use, copy, modify, merge, publish,
  9. * distribute, sublicense, and/or sell copies of the Software, and to permit
  10. * persons to whom the Software is furnished to do so, subject to the
  11. * following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included
  14. * in all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  19. * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  20. * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  21. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  22. * USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. */
  24. var test = require('mocha').test;
  25. var assert = require('assert');
  26. var nodeURL = require('url');
  27. var url = require('../url');
  28. /*
  29. * URLs to parse, and expected data
  30. * { url : parsed }
  31. */
  32. var parseTests = {
  33. '//some_path': {
  34. href: '//some_path',
  35. pathname: '//some_path',
  36. path: '//some_path'
  37. },
  38. 'http:\\\\evil-phisher\\foo.html#h\\a\\s\\h': {
  39. protocol: 'http:',
  40. slashes: true,
  41. host: 'evil-phisher',
  42. hostname: 'evil-phisher',
  43. pathname: '/foo.html',
  44. path: '/foo.html',
  45. hash: '#h%5Ca%5Cs%5Ch',
  46. href: 'http://evil-phisher/foo.html#h%5Ca%5Cs%5Ch'
  47. },
  48. 'http:\\\\evil-phisher\\foo.html?json="\\"foo\\""#h\\a\\s\\h': {
  49. protocol: 'http:',
  50. slashes: true,
  51. host: 'evil-phisher',
  52. hostname: 'evil-phisher',
  53. pathname: '/foo.html',
  54. search: '?json=%22%5C%22foo%5C%22%22',
  55. query: 'json=%22%5C%22foo%5C%22%22',
  56. path: '/foo.html?json=%22%5C%22foo%5C%22%22',
  57. hash: '#h%5Ca%5Cs%5Ch',
  58. href: 'http://evil-phisher/foo.html?json=%22%5C%22foo%5C%22%22#h%5Ca%5Cs%5Ch'
  59. },
  60. 'http:\\\\evil-phisher\\foo.html#h\\a\\s\\h?blarg': {
  61. protocol: 'http:',
  62. slashes: true,
  63. host: 'evil-phisher',
  64. hostname: 'evil-phisher',
  65. pathname: '/foo.html',
  66. path: '/foo.html',
  67. hash: '#h%5Ca%5Cs%5Ch?blarg',
  68. href: 'http://evil-phisher/foo.html#h%5Ca%5Cs%5Ch?blarg'
  69. },
  70. 'http:\\\\evil-phisher\\foo.html': {
  71. protocol: 'http:',
  72. slashes: true,
  73. host: 'evil-phisher',
  74. hostname: 'evil-phisher',
  75. pathname: '/foo.html',
  76. path: '/foo.html',
  77. href: 'http://evil-phisher/foo.html'
  78. },
  79. 'HTTP://www.example.com/': {
  80. href: 'http://www.example.com/',
  81. protocol: 'http:',
  82. slashes: true,
  83. host: 'www.example.com',
  84. hostname: 'www.example.com',
  85. pathname: '/',
  86. path: '/'
  87. },
  88. 'HTTP://www.example.com': {
  89. href: 'http://www.example.com/',
  90. protocol: 'http:',
  91. slashes: true,
  92. host: 'www.example.com',
  93. hostname: 'www.example.com',
  94. pathname: '/',
  95. path: '/'
  96. },
  97. 'http://www.ExAmPlE.com/': {
  98. href: 'http://www.example.com/',
  99. protocol: 'http:',
  100. slashes: true,
  101. host: 'www.example.com',
  102. hostname: 'www.example.com',
  103. pathname: '/',
  104. path: '/'
  105. },
  106. 'http://user:pw@www.ExAmPlE.com/': {
  107. href: 'http://user:pw@www.example.com/',
  108. protocol: 'http:',
  109. slashes: true,
  110. auth: 'user:pw',
  111. host: 'www.example.com',
  112. hostname: 'www.example.com',
  113. pathname: '/',
  114. path: '/'
  115. },
  116. 'http://USER:PW@www.ExAmPlE.com/': {
  117. href: 'http://USER:PW@www.example.com/',
  118. protocol: 'http:',
  119. slashes: true,
  120. auth: 'USER:PW',
  121. host: 'www.example.com',
  122. hostname: 'www.example.com',
  123. pathname: '/',
  124. path: '/'
  125. },
  126. 'http://user@www.example.com/': {
  127. href: 'http://user@www.example.com/',
  128. protocol: 'http:',
  129. slashes: true,
  130. auth: 'user',
  131. host: 'www.example.com',
  132. hostname: 'www.example.com',
  133. pathname: '/',
  134. path: '/'
  135. },
  136. 'http://user%3Apw@www.example.com/': {
  137. href: 'http://user:pw@www.example.com/',
  138. protocol: 'http:',
  139. slashes: true,
  140. auth: 'user:pw',
  141. host: 'www.example.com',
  142. hostname: 'www.example.com',
  143. pathname: '/',
  144. path: '/'
  145. },
  146. 'http://x.com/path?that\'s#all, folks': {
  147. href: 'http://x.com/path?that%27s#all,%20folks',
  148. protocol: 'http:',
  149. slashes: true,
  150. host: 'x.com',
  151. hostname: 'x.com',
  152. search: '?that%27s',
  153. query: 'that%27s',
  154. pathname: '/path',
  155. hash: '#all,%20folks',
  156. path: '/path?that%27s'
  157. },
  158. 'HTTP://X.COM/Y': {
  159. href: 'http://x.com/Y',
  160. protocol: 'http:',
  161. slashes: true,
  162. host: 'x.com',
  163. hostname: 'x.com',
  164. pathname: '/Y',
  165. path: '/Y'
  166. },
  167. /*
  168. * + not an invalid host character
  169. * per https://url.spec.whatwg.org/#host-parsing
  170. */
  171. 'http://x.y.com+a/b/c': {
  172. href: 'http://x.y.com+a/b/c',
  173. protocol: 'http:',
  174. slashes: true,
  175. host: 'x.y.com+a',
  176. hostname: 'x.y.com+a',
  177. pathname: '/b/c',
  178. path: '/b/c'
  179. },
  180. // an unexpected invalid char in the hostname.
  181. 'HtTp://x.y.cOm;a/b/c?d=e#f g<h>i': {
  182. href: 'http://x.y.com/;a/b/c?d=e#f%20g%3Ch%3Ei',
  183. protocol: 'http:',
  184. slashes: true,
  185. host: 'x.y.com',
  186. hostname: 'x.y.com',
  187. pathname: ';a/b/c',
  188. search: '?d=e',
  189. query: 'd=e',
  190. hash: '#f%20g%3Ch%3Ei',
  191. path: ';a/b/c?d=e'
  192. },
  193. // make sure that we don't accidentally lcast the path parts.
  194. 'HtTp://x.y.cOm;A/b/c?d=e#f g<h>i': {
  195. href: 'http://x.y.com/;A/b/c?d=e#f%20g%3Ch%3Ei',
  196. protocol: 'http:',
  197. slashes: true,
  198. host: 'x.y.com',
  199. hostname: 'x.y.com',
  200. pathname: ';A/b/c',
  201. search: '?d=e',
  202. query: 'd=e',
  203. hash: '#f%20g%3Ch%3Ei',
  204. path: ';A/b/c?d=e'
  205. },
  206. 'http://x...y...#p': {
  207. href: 'http://x...y.../#p',
  208. protocol: 'http:',
  209. slashes: true,
  210. host: 'x...y...',
  211. hostname: 'x...y...',
  212. hash: '#p',
  213. pathname: '/',
  214. path: '/'
  215. },
  216. 'http://x/p/"quoted"': {
  217. href: 'http://x/p/%22quoted%22',
  218. protocol: 'http:',
  219. slashes: true,
  220. host: 'x',
  221. hostname: 'x',
  222. pathname: '/p/%22quoted%22',
  223. path: '/p/%22quoted%22'
  224. },
  225. '<http://goo.corn/bread> Is a URL!': {
  226. href: '%3Chttp://goo.corn/bread%3E%20Is%20a%20URL!',
  227. pathname: '%3Chttp://goo.corn/bread%3E%20Is%20a%20URL!',
  228. path: '%3Chttp://goo.corn/bread%3E%20Is%20a%20URL!'
  229. },
  230. 'http://www.narwhaljs.org/blog/categories?id=news': {
  231. href: 'http://www.narwhaljs.org/blog/categories?id=news',
  232. protocol: 'http:',
  233. slashes: true,
  234. host: 'www.narwhaljs.org',
  235. hostname: 'www.narwhaljs.org',
  236. search: '?id=news',
  237. query: 'id=news',
  238. pathname: '/blog/categories',
  239. path: '/blog/categories?id=news'
  240. },
  241. 'http://mt0.google.com/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s=': {
  242. href: 'http://mt0.google.com/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s=',
  243. protocol: 'http:',
  244. slashes: true,
  245. host: 'mt0.google.com',
  246. hostname: 'mt0.google.com',
  247. pathname: '/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s=',
  248. path: '/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s='
  249. },
  250. 'http://mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=': {
  251. href: 'http://mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=',
  252. protocol: 'http:',
  253. slashes: true,
  254. host: 'mt0.google.com',
  255. hostname: 'mt0.google.com',
  256. search: '???&hl=en&src=api&x=2&y=2&z=3&s=',
  257. query: '??&hl=en&src=api&x=2&y=2&z=3&s=',
  258. pathname: '/vt/lyrs=m@114',
  259. path: '/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s='
  260. },
  261. 'http://user:pass@mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=': {
  262. href: 'http://user:pass@mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=',
  263. protocol: 'http:',
  264. slashes: true,
  265. host: 'mt0.google.com',
  266. auth: 'user:pass',
  267. hostname: 'mt0.google.com',
  268. search: '???&hl=en&src=api&x=2&y=2&z=3&s=',
  269. query: '??&hl=en&src=api&x=2&y=2&z=3&s=',
  270. pathname: '/vt/lyrs=m@114',
  271. path: '/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s='
  272. },
  273. 'file:///etc/passwd': {
  274. href: 'file:///etc/passwd',
  275. slashes: true,
  276. protocol: 'file:',
  277. pathname: '/etc/passwd',
  278. hostname: '',
  279. host: '',
  280. path: '/etc/passwd'
  281. },
  282. 'file://localhost/etc/passwd': {
  283. href: 'file://localhost/etc/passwd',
  284. protocol: 'file:',
  285. slashes: true,
  286. pathname: '/etc/passwd',
  287. hostname: 'localhost',
  288. host: 'localhost',
  289. path: '/etc/passwd'
  290. },
  291. 'file://foo/etc/passwd': {
  292. href: 'file://foo/etc/passwd',
  293. protocol: 'file:',
  294. slashes: true,
  295. pathname: '/etc/passwd',
  296. hostname: 'foo',
  297. host: 'foo',
  298. path: '/etc/passwd'
  299. },
  300. 'file:///etc/node/': {
  301. href: 'file:///etc/node/',
  302. slashes: true,
  303. protocol: 'file:',
  304. pathname: '/etc/node/',
  305. hostname: '',
  306. host: '',
  307. path: '/etc/node/'
  308. },
  309. 'file://localhost/etc/node/': {
  310. href: 'file://localhost/etc/node/',
  311. protocol: 'file:',
  312. slashes: true,
  313. pathname: '/etc/node/',
  314. hostname: 'localhost',
  315. host: 'localhost',
  316. path: '/etc/node/'
  317. },
  318. 'file://foo/etc/node/': {
  319. href: 'file://foo/etc/node/',
  320. protocol: 'file:',
  321. slashes: true,
  322. pathname: '/etc/node/',
  323. hostname: 'foo',
  324. host: 'foo',
  325. path: '/etc/node/'
  326. },
  327. 'http:/baz/../foo/bar': {
  328. href: 'http:/baz/../foo/bar',
  329. protocol: 'http:',
  330. pathname: '/baz/../foo/bar',
  331. path: '/baz/../foo/bar'
  332. },
  333. 'http://user:pass@example.com:8000/foo/bar?baz=quux#frag': {
  334. href: 'http://user:pass@example.com:8000/foo/bar?baz=quux#frag',
  335. protocol: 'http:',
  336. slashes: true,
  337. host: 'example.com:8000',
  338. auth: 'user:pass',
  339. port: '8000',
  340. hostname: 'example.com',
  341. hash: '#frag',
  342. search: '?baz=quux',
  343. query: 'baz=quux',
  344. pathname: '/foo/bar',
  345. path: '/foo/bar?baz=quux'
  346. },
  347. '//user:pass@example.com:8000/foo/bar?baz=quux#frag': {
  348. href: '//user:pass@example.com:8000/foo/bar?baz=quux#frag',
  349. slashes: true,
  350. host: 'example.com:8000',
  351. auth: 'user:pass',
  352. port: '8000',
  353. hostname: 'example.com',
  354. hash: '#frag',
  355. search: '?baz=quux',
  356. query: 'baz=quux',
  357. pathname: '/foo/bar',
  358. path: '/foo/bar?baz=quux'
  359. },
  360. '/foo/bar?baz=quux#frag': {
  361. href: '/foo/bar?baz=quux#frag',
  362. hash: '#frag',
  363. search: '?baz=quux',
  364. query: 'baz=quux',
  365. pathname: '/foo/bar',
  366. path: '/foo/bar?baz=quux'
  367. },
  368. 'http:/foo/bar?baz=quux#frag': {
  369. href: 'http:/foo/bar?baz=quux#frag',
  370. protocol: 'http:',
  371. hash: '#frag',
  372. search: '?baz=quux',
  373. query: 'baz=quux',
  374. pathname: '/foo/bar',
  375. path: '/foo/bar?baz=quux'
  376. },
  377. 'mailto:foo@bar.com?subject=hello': {
  378. href: 'mailto:foo@bar.com?subject=hello',
  379. protocol: 'mailto:',
  380. host: 'bar.com',
  381. auth: 'foo',
  382. hostname: 'bar.com',
  383. search: '?subject=hello',
  384. query: 'subject=hello',
  385. path: '?subject=hello'
  386. },
  387. 'javascript:alert(\'hello\');': {
  388. href: 'javascript:alert(\'hello\');',
  389. protocol: 'javascript:',
  390. pathname: 'alert(\'hello\');',
  391. path: 'alert(\'hello\');'
  392. },
  393. 'xmpp:isaacschlueter@jabber.org': {
  394. href: 'xmpp:isaacschlueter@jabber.org',
  395. protocol: 'xmpp:',
  396. host: 'jabber.org',
  397. auth: 'isaacschlueter',
  398. hostname: 'jabber.org'
  399. },
  400. 'http://atpass:foo%40bar@127.0.0.1:8080/path?search=foo#bar': {
  401. href: 'http://atpass:foo%40bar@127.0.0.1:8080/path?search=foo#bar',
  402. protocol: 'http:',
  403. slashes: true,
  404. host: '127.0.0.1:8080',
  405. auth: 'atpass:foo@bar',
  406. hostname: '127.0.0.1',
  407. port: '8080',
  408. pathname: '/path',
  409. search: '?search=foo',
  410. query: 'search=foo',
  411. hash: '#bar',
  412. path: '/path?search=foo'
  413. },
  414. 'svn+ssh://foo/bar': {
  415. href: 'svn+ssh://foo/bar',
  416. host: 'foo',
  417. hostname: 'foo',
  418. protocol: 'svn+ssh:',
  419. pathname: '/bar',
  420. path: '/bar',
  421. slashes: true
  422. },
  423. 'dash-test://foo/bar': {
  424. href: 'dash-test://foo/bar',
  425. host: 'foo',
  426. hostname: 'foo',
  427. protocol: 'dash-test:',
  428. pathname: '/bar',
  429. path: '/bar',
  430. slashes: true
  431. },
  432. 'dash-test:foo/bar': {
  433. href: 'dash-test:foo/bar',
  434. host: 'foo',
  435. hostname: 'foo',
  436. protocol: 'dash-test:',
  437. pathname: '/bar',
  438. path: '/bar'
  439. },
  440. 'dot.test://foo/bar': {
  441. href: 'dot.test://foo/bar',
  442. host: 'foo',
  443. hostname: 'foo',
  444. protocol: 'dot.test:',
  445. pathname: '/bar',
  446. path: '/bar',
  447. slashes: true
  448. },
  449. 'dot.test:foo/bar': {
  450. href: 'dot.test:foo/bar',
  451. host: 'foo',
  452. hostname: 'foo',
  453. protocol: 'dot.test:',
  454. pathname: '/bar',
  455. path: '/bar'
  456. },
  457. // IDNA tests
  458. 'http://www.日本語.com/': {
  459. href: 'http://www.xn--wgv71a119e.com/',
  460. protocol: 'http:',
  461. slashes: true,
  462. host: 'www.xn--wgv71a119e.com',
  463. hostname: 'www.xn--wgv71a119e.com',
  464. pathname: '/',
  465. path: '/'
  466. },
  467. 'http://example.Bücher.com/': {
  468. href: 'http://example.xn--bcher-kva.com/',
  469. protocol: 'http:',
  470. slashes: true,
  471. host: 'example.xn--bcher-kva.com',
  472. hostname: 'example.xn--bcher-kva.com',
  473. pathname: '/',
  474. path: '/'
  475. },
  476. 'http://www.Äffchen.com/': {
  477. href: 'http://www.xn--ffchen-9ta.com/',
  478. protocol: 'http:',
  479. slashes: true,
  480. host: 'www.xn--ffchen-9ta.com',
  481. hostname: 'www.xn--ffchen-9ta.com',
  482. pathname: '/',
  483. path: '/'
  484. },
  485. 'http://www.Äffchen.cOm;A/b/c?d=e#f g<h>i': {
  486. href: 'http://www.xn--ffchen-9ta.com/;A/b/c?d=e#f%20g%3Ch%3Ei',
  487. protocol: 'http:',
  488. slashes: true,
  489. host: 'www.xn--ffchen-9ta.com',
  490. hostname: 'www.xn--ffchen-9ta.com',
  491. pathname: ';A/b/c',
  492. search: '?d=e',
  493. query: 'd=e',
  494. hash: '#f%20g%3Ch%3Ei',
  495. path: ';A/b/c?d=e'
  496. },
  497. 'http://SÉLIER.COM/': {
  498. href: 'http://xn--slier-bsa.com/',
  499. protocol: 'http:',
  500. slashes: true,
  501. host: 'xn--slier-bsa.com',
  502. hostname: 'xn--slier-bsa.com',
  503. pathname: '/',
  504. path: '/'
  505. },
  506. 'http://ليهمابتكلموشعربي؟.ي؟/': {
  507. href: 'http://xn--egbpdaj6bu4bxfgehfvwxn.xn--egb9f/',
  508. protocol: 'http:',
  509. slashes: true,
  510. host: 'xn--egbpdaj6bu4bxfgehfvwxn.xn--egb9f',
  511. hostname: 'xn--egbpdaj6bu4bxfgehfvwxn.xn--egb9f',
  512. pathname: '/',
  513. path: '/'
  514. },
  515. 'http://➡.ws/➡': {
  516. href: 'http://xn--hgi.ws/➡',
  517. protocol: 'http:',
  518. slashes: true,
  519. host: 'xn--hgi.ws',
  520. hostname: 'xn--hgi.ws',
  521. pathname: '/➡',
  522. path: '/➡'
  523. },
  524. 'http://bucket_name.s3.amazonaws.com/image.jpg': {
  525. protocol: 'http:',
  526. slashes: true,
  527. host: 'bucket_name.s3.amazonaws.com',
  528. hostname: 'bucket_name.s3.amazonaws.com',
  529. pathname: '/image.jpg',
  530. href: 'http://bucket_name.s3.amazonaws.com/image.jpg',
  531. path: '/image.jpg'
  532. },
  533. 'git+http://github.com/joyent/node.git': {
  534. protocol: 'git+http:',
  535. slashes: true,
  536. host: 'github.com',
  537. hostname: 'github.com',
  538. pathname: '/joyent/node.git',
  539. path: '/joyent/node.git',
  540. href: 'git+http://github.com/joyent/node.git'
  541. },
  542. /*
  543. * if local1@domain1 is uses as a relative URL it may
  544. * be parse into auth@hostname, but here there is no
  545. * way to make it work in url.parse, I add the test to be explicit
  546. */
  547. 'local1@domain1': {
  548. pathname: 'local1@domain1',
  549. path: 'local1@domain1',
  550. href: 'local1@domain1'
  551. },
  552. /*
  553. * While this may seem counter-intuitive, a browser will parse
  554. * <a href='www.google.com'> as a path.
  555. */
  556. 'www.example.com': {
  557. href: 'www.example.com',
  558. pathname: 'www.example.com',
  559. path: 'www.example.com'
  560. },
  561. // ipv6 support
  562. '[fe80::1]': {
  563. href: '[fe80::1]',
  564. pathname: '[fe80::1]',
  565. path: '[fe80::1]'
  566. },
  567. 'coap://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]': {
  568. protocol: 'coap:',
  569. slashes: true,
  570. host: '[fedc:ba98:7654:3210:fedc:ba98:7654:3210]',
  571. hostname: 'fedc:ba98:7654:3210:fedc:ba98:7654:3210',
  572. href: 'coap://[fedc:ba98:7654:3210:fedc:ba98:7654:3210]/',
  573. pathname: '/',
  574. path: '/'
  575. },
  576. 'coap://[1080:0:0:0:8:800:200C:417A]:61616/': {
  577. protocol: 'coap:',
  578. slashes: true,
  579. host: '[1080:0:0:0:8:800:200c:417a]:61616',
  580. port: '61616',
  581. hostname: '1080:0:0:0:8:800:200c:417a',
  582. href: 'coap://[1080:0:0:0:8:800:200c:417a]:61616/',
  583. pathname: '/',
  584. path: '/'
  585. },
  586. 'http://user:password@[3ffe:2a00:100:7031::1]:8080': {
  587. protocol: 'http:',
  588. slashes: true,
  589. auth: 'user:password',
  590. host: '[3ffe:2a00:100:7031::1]:8080',
  591. port: '8080',
  592. hostname: '3ffe:2a00:100:7031::1',
  593. href: 'http://user:password@[3ffe:2a00:100:7031::1]:8080/',
  594. pathname: '/',
  595. path: '/'
  596. },
  597. 'coap://u:p@[::192.9.5.5]:61616/.well-known/r?n=Temperature': {
  598. protocol: 'coap:',
  599. slashes: true,
  600. auth: 'u:p',
  601. host: '[::192.9.5.5]:61616',
  602. port: '61616',
  603. hostname: '::192.9.5.5',
  604. href: 'coap://u:p@[::192.9.5.5]:61616/.well-known/r?n=Temperature',
  605. search: '?n=Temperature',
  606. query: 'n=Temperature',
  607. pathname: '/.well-known/r',
  608. path: '/.well-known/r?n=Temperature'
  609. },
  610. // empty port
  611. 'http://example.com:': {
  612. protocol: 'http:',
  613. slashes: true,
  614. host: 'example.com',
  615. hostname: 'example.com',
  616. href: 'http://example.com/',
  617. pathname: '/',
  618. path: '/'
  619. },
  620. 'http://example.com:/a/b.html': {
  621. protocol: 'http:',
  622. slashes: true,
  623. host: 'example.com',
  624. hostname: 'example.com',
  625. href: 'http://example.com/a/b.html',
  626. pathname: '/a/b.html',
  627. path: '/a/b.html'
  628. },
  629. 'http://example.com:?a=b': {
  630. protocol: 'http:',
  631. slashes: true,
  632. host: 'example.com',
  633. hostname: 'example.com',
  634. href: 'http://example.com/?a=b',
  635. search: '?a=b',
  636. query: 'a=b',
  637. pathname: '/',
  638. path: '/?a=b'
  639. },
  640. 'http://example.com:#abc': {
  641. protocol: 'http:',
  642. slashes: true,
  643. host: 'example.com',
  644. hostname: 'example.com',
  645. href: 'http://example.com/#abc',
  646. hash: '#abc',
  647. pathname: '/',
  648. path: '/'
  649. },
  650. 'http://[fe80::1]:/a/b?a=b#abc': {
  651. protocol: 'http:',
  652. slashes: true,
  653. host: '[fe80::1]',
  654. hostname: 'fe80::1',
  655. href: 'http://[fe80::1]/a/b?a=b#abc',
  656. search: '?a=b',
  657. query: 'a=b',
  658. hash: '#abc',
  659. pathname: '/a/b',
  660. path: '/a/b?a=b'
  661. },
  662. 'http://-lovemonsterz.tumblr.com/rss': {
  663. protocol: 'http:',
  664. slashes: true,
  665. host: '-lovemonsterz.tumblr.com',
  666. hostname: '-lovemonsterz.tumblr.com',
  667. href: 'http://-lovemonsterz.tumblr.com/rss',
  668. pathname: '/rss',
  669. path: '/rss'
  670. },
  671. 'http://-lovemonsterz.tumblr.com:80/rss': {
  672. protocol: 'http:',
  673. slashes: true,
  674. port: '80',
  675. host: '-lovemonsterz.tumblr.com:80',
  676. hostname: '-lovemonsterz.tumblr.com',
  677. href: 'http://-lovemonsterz.tumblr.com:80/rss',
  678. pathname: '/rss',
  679. path: '/rss'
  680. },
  681. 'http://user:pass@-lovemonsterz.tumblr.com/rss': {
  682. protocol: 'http:',
  683. slashes: true,
  684. auth: 'user:pass',
  685. host: '-lovemonsterz.tumblr.com',
  686. hostname: '-lovemonsterz.tumblr.com',
  687. href: 'http://user:pass@-lovemonsterz.tumblr.com/rss',
  688. pathname: '/rss',
  689. path: '/rss'
  690. },
  691. 'http://user:pass@-lovemonsterz.tumblr.com:80/rss': {
  692. protocol: 'http:',
  693. slashes: true,
  694. auth: 'user:pass',
  695. port: '80',
  696. host: '-lovemonsterz.tumblr.com:80',
  697. hostname: '-lovemonsterz.tumblr.com',
  698. href: 'http://user:pass@-lovemonsterz.tumblr.com:80/rss',
  699. pathname: '/rss',
  700. path: '/rss'
  701. },
  702. 'http://_jabber._tcp.google.com/test': {
  703. protocol: 'http:',
  704. slashes: true,
  705. host: '_jabber._tcp.google.com',
  706. hostname: '_jabber._tcp.google.com',
  707. href: 'http://_jabber._tcp.google.com/test',
  708. pathname: '/test',
  709. path: '/test'
  710. },
  711. 'http://user:pass@_jabber._tcp.google.com/test': {
  712. protocol: 'http:',
  713. slashes: true,
  714. auth: 'user:pass',
  715. host: '_jabber._tcp.google.com',
  716. hostname: '_jabber._tcp.google.com',
  717. href: 'http://user:pass@_jabber._tcp.google.com/test',
  718. pathname: '/test',
  719. path: '/test'
  720. },
  721. 'http://_jabber._tcp.google.com:80/test': {
  722. protocol: 'http:',
  723. slashes: true,
  724. port: '80',
  725. host: '_jabber._tcp.google.com:80',
  726. hostname: '_jabber._tcp.google.com',
  727. href: 'http://_jabber._tcp.google.com:80/test',
  728. pathname: '/test',
  729. path: '/test'
  730. },
  731. 'http://user:pass@_jabber._tcp.google.com:80/test': {
  732. protocol: 'http:',
  733. slashes: true,
  734. auth: 'user:pass',
  735. port: '80',
  736. host: '_jabber._tcp.google.com:80',
  737. hostname: '_jabber._tcp.google.com',
  738. href: 'http://user:pass@_jabber._tcp.google.com:80/test',
  739. pathname: '/test',
  740. path: '/test'
  741. },
  742. 'http://x:1/\' <>"`/{}|\\^~`/': {
  743. protocol: 'http:',
  744. slashes: true,
  745. host: 'x:1',
  746. port: '1',
  747. hostname: 'x',
  748. pathname: '/%27%20%3C%3E%22%60/%7B%7D%7C/%5E~%60/',
  749. path: '/%27%20%3C%3E%22%60/%7B%7D%7C/%5E~%60/',
  750. href: 'http://x:1/%27%20%3C%3E%22%60/%7B%7D%7C/%5E~%60/'
  751. },
  752. 'http://a@b@c/': {
  753. protocol: 'http:',
  754. slashes: true,
  755. auth: 'a@b',
  756. host: 'c',
  757. hostname: 'c',
  758. href: 'http://a%40b@c/',
  759. path: '/',
  760. pathname: '/'
  761. },
  762. 'http://a@b?@c': {
  763. protocol: 'http:',
  764. slashes: true,
  765. auth: 'a',
  766. host: 'b',
  767. hostname: 'b',
  768. href: 'http://a@b/?@c',
  769. path: '/?@c',
  770. pathname: '/',
  771. search: '?@c',
  772. query: '@c'
  773. },
  774. 'http://a\r" \t\n<\'b:b@c\r\nd/e?f': {
  775. protocol: 'http:',
  776. slashes: true,
  777. auth: 'a\r" \t\n<\'b:b',
  778. host: 'c',
  779. port: null,
  780. hostname: 'c',
  781. hash: null,
  782. search: '?f',
  783. query: 'f',
  784. pathname: '%0D%0Ad/e',
  785. path: '%0D%0Ad/e?f',
  786. href: 'http://a%0D%22%20%09%0A%3C\'b:b@c/%0D%0Ad/e?f'
  787. },
  788. // git urls used by npm
  789. 'git+ssh://git@github.com:npm/npm': {
  790. protocol: 'git+ssh:',
  791. slashes: true,
  792. auth: 'git',
  793. host: 'github.com',
  794. port: null,
  795. hostname: 'github.com',
  796. hash: null,
  797. search: null,
  798. query: null,
  799. pathname: '/:npm/npm',
  800. path: '/:npm/npm',
  801. href: 'git+ssh://git@github.com/:npm/npm'
  802. }
  803. };
  804. Object.keys(parseTests).forEach(function (u) {
  805. test('parse(' + u + ')', function () {
  806. var actual = url.parse(u);
  807. var spaced = url.parse(' \t ' + u + '\n\t');
  808. var expected = parseTests[u];
  809. Object.keys(actual).forEach(function (i) {
  810. if (expected[i] === undefined && actual[i] === null) {
  811. expected[i] = null;
  812. }
  813. });
  814. assert.deepEqual(actual, expected);
  815. assert.deepEqual(spaced, expected);
  816. var expected = parseTests[u].href,
  817. actual = url.format(parseTests[u]);
  818. assert.equal(actual, expected, 'format(' + u + ') == ' + u + '\nactual:' + actual);
  819. });
  820. });
  821. var parseTestsWithQueryString = {
  822. '/foo/bar?baz=quux#frag': {
  823. href: '/foo/bar?baz=quux#frag',
  824. hash: '#frag',
  825. search: '?baz=quux',
  826. query: {
  827. baz: 'quux'
  828. },
  829. pathname: '/foo/bar',
  830. path: '/foo/bar?baz=quux'
  831. },
  832. 'http://example.com': {
  833. href: 'http://example.com/',
  834. protocol: 'http:',
  835. slashes: true,
  836. host: 'example.com',
  837. hostname: 'example.com',
  838. query: {},
  839. search: '',
  840. pathname: '/',
  841. path: '/'
  842. },
  843. '/example': {
  844. protocol: null,
  845. slashes: null,
  846. auth: null,
  847. host: null,
  848. port: null,
  849. hostname: null,
  850. hash: null,
  851. search: '',
  852. query: {},
  853. pathname: '/example',
  854. path: '/example',
  855. href: '/example'
  856. },
  857. '/example?query=value': {
  858. protocol: null,
  859. slashes: null,
  860. auth: null,
  861. host: null,
  862. port: null,
  863. hostname: null,
  864. hash: null,
  865. search: '?query=value',
  866. query: { query: 'value' },
  867. pathname: '/example',
  868. path: '/example?query=value',
  869. href: '/example?query=value'
  870. }
  871. };
  872. Object.keys(parseTestsWithQueryString).forEach(function (u) {
  873. test('parse(' + u + ')', function () {
  874. var actual = url.parse(u, true);
  875. var expected = parseTestsWithQueryString[u];
  876. for (var i in actual) {
  877. if (actual[i] === null && expected[i] === undefined) {
  878. expected[i] = null;
  879. }
  880. }
  881. assert.deepEqual(actual, expected);
  882. });
  883. });
  884. /*
  885. * some extra formatting tests, just to verify
  886. * that it'll format slightly wonky content to a valid url.
  887. */
  888. var formatTests = {
  889. 'http://example.com?': {
  890. href: 'http://example.com/?',
  891. protocol: 'http:',
  892. slashes: true,
  893. host: 'example.com',
  894. hostname: 'example.com',
  895. search: '?',
  896. query: {},
  897. pathname: '/'
  898. },
  899. 'http://example.com?foo=bar#frag': {
  900. href: 'http://example.com/?foo=bar#frag',
  901. protocol: 'http:',
  902. host: 'example.com',
  903. hostname: 'example.com',
  904. hash: '#frag',
  905. search: '?foo=bar',
  906. query: 'foo=bar',
  907. pathname: '/'
  908. },
  909. 'http://example.com?foo=@bar#frag': {
  910. href: 'http://example.com/?foo=@bar#frag',
  911. protocol: 'http:',
  912. host: 'example.com',
  913. hostname: 'example.com',
  914. hash: '#frag',
  915. search: '?foo=@bar',
  916. query: 'foo=@bar',
  917. pathname: '/'
  918. },
  919. 'http://example.com?foo=/bar/#frag': {
  920. href: 'http://example.com/?foo=/bar/#frag',
  921. protocol: 'http:',
  922. host: 'example.com',
  923. hostname: 'example.com',
  924. hash: '#frag',
  925. search: '?foo=/bar/',
  926. query: 'foo=/bar/',
  927. pathname: '/'
  928. },
  929. 'http://example.com?foo=?bar/#frag': {
  930. href: 'http://example.com/?foo=?bar/#frag',
  931. protocol: 'http:',
  932. host: 'example.com',
  933. hostname: 'example.com',
  934. hash: '#frag',
  935. search: '?foo=?bar/',
  936. query: 'foo=?bar/',
  937. pathname: '/'
  938. },
  939. 'http://example.com#frag=?bar/#frag': {
  940. href: 'http://example.com/#frag=?bar/#frag',
  941. protocol: 'http:',
  942. host: 'example.com',
  943. hostname: 'example.com',
  944. hash: '#frag=?bar/#frag',
  945. pathname: '/'
  946. },
  947. 'http://google.com" onload="alert(42)/': {
  948. href: 'http://google.com/%22%20onload=%22alert(42)/',
  949. protocol: 'http:',
  950. host: 'google.com',
  951. pathname: '/%22%20onload=%22alert(42)/'
  952. },
  953. 'http://a.com/a/b/c?s#h': {
  954. href: 'http://a.com/a/b/c?s#h',
  955. protocol: 'http',
  956. host: 'a.com',
  957. pathname: 'a/b/c',
  958. hash: 'h',
  959. search: 's'
  960. },
  961. 'xmpp:isaacschlueter@jabber.org': {
  962. href: 'xmpp:isaacschlueter@jabber.org',
  963. protocol: 'xmpp:',
  964. host: 'jabber.org',
  965. auth: 'isaacschlueter',
  966. hostname: 'jabber.org'
  967. },
  968. 'http://atpass:foo%40bar@127.0.0.1/': {
  969. href: 'http://atpass:foo%40bar@127.0.0.1/',
  970. auth: 'atpass:foo@bar',
  971. hostname: '127.0.0.1',
  972. protocol: 'http:',
  973. pathname: '/'
  974. },
  975. 'http://atslash%2F%40:%2F%40@foo/': {
  976. href: 'http://atslash%2F%40:%2F%40@foo/',
  977. auth: 'atslash/@:/@',
  978. hostname: 'foo',
  979. protocol: 'http:',
  980. pathname: '/'
  981. },
  982. 'svn+ssh://foo/bar': {
  983. href: 'svn+ssh://foo/bar',
  984. hostname: 'foo',
  985. protocol: 'svn+ssh:',
  986. pathname: '/bar',
  987. slashes: true
  988. },
  989. 'dash-test://foo/bar': {
  990. href: 'dash-test://foo/bar',
  991. hostname: 'foo',
  992. protocol: 'dash-test:',
  993. pathname: '/bar',
  994. slashes: true
  995. },
  996. 'dash-test:foo/bar': {
  997. href: 'dash-test:foo/bar',
  998. hostname: 'foo',
  999. protocol: 'dash-test:',
  1000. pathname: '/bar'
  1001. },
  1002. 'dot.test://foo/bar': {
  1003. href: 'dot.test://foo/bar',
  1004. hostname: 'foo',
  1005. protocol: 'dot.test:',
  1006. pathname: '/bar',
  1007. slashes: true
  1008. },
  1009. 'dot.test:foo/bar': {
  1010. href: 'dot.test:foo/bar',
  1011. hostname: 'foo',
  1012. protocol: 'dot.test:',
  1013. pathname: '/bar'
  1014. },
  1015. // ipv6 support
  1016. 'coap:u:p@[::1]:61616/.well-known/r?n=Temperature': {
  1017. href: 'coap:u:p@[::1]:61616/.well-known/r?n=Temperature',
  1018. protocol: 'coap:',
  1019. auth: 'u:p',
  1020. hostname: '::1',
  1021. port: '61616',
  1022. pathname: '/.well-known/r',
  1023. search: 'n=Temperature'
  1024. },
  1025. 'coap:[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616/s/stopButton': {
  1026. href: 'coap:[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616/s/stopButton',
  1027. protocol: 'coap',
  1028. host: '[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616',
  1029. pathname: '/s/stopButton'
  1030. },
  1031. /*
  1032. * encode context-specific delimiters in path and query, but do not touch
  1033. * other non-delimiter chars like `%`.
  1034. * <https://github.com/joyent/node/issues/4082>
  1035. */
  1036. // `#`,`?` in path
  1037. '/path/to/%%23%3F+=&.txt?foo=theA1#bar': {
  1038. href: '/path/to/%%23%3F+=&.txt?foo=theA1#bar',
  1039. pathname: '/path/to/%#?+=&.txt',
  1040. query: {
  1041. foo: 'theA1'
  1042. },
  1043. hash: '#bar'
  1044. },
  1045. // `#`,`?` in path + `#` in query
  1046. '/path/to/%%23%3F+=&.txt?foo=the%231#bar': {
  1047. href: '/path/to/%%23%3F+=&.txt?foo=the%231#bar',
  1048. pathname: '/path/to/%#?+=&.txt',
  1049. query: {
  1050. foo: 'the#1'
  1051. },
  1052. hash: '#bar'
  1053. },
  1054. // `?` and `#` in path and search
  1055. 'http://ex.com/foo%3F100%m%23r?abc=the%231?&foo=bar#frag': {
  1056. href: 'http://ex.com/foo%3F100%m%23r?abc=the%231?&foo=bar#frag',
  1057. protocol: 'http:',
  1058. hostname: 'ex.com',
  1059. hash: '#frag',
  1060. search: '?abc=the#1?&foo=bar',
  1061. pathname: '/foo?100%m#r'
  1062. },
  1063. // `?` and `#` in search only
  1064. 'http://ex.com/fooA100%mBr?abc=the%231?&foo=bar#frag': {
  1065. href: 'http://ex.com/fooA100%mBr?abc=the%231?&foo=bar#frag',
  1066. protocol: 'http:',
  1067. hostname: 'ex.com',
  1068. hash: '#frag',
  1069. search: '?abc=the#1?&foo=bar',
  1070. pathname: '/fooA100%mBr'
  1071. },
  1072. // colons in keys
  1073. 'https://cdpn.io/test?custom%3Aid=12': {
  1074. href: 'https://cdpn.io/test?custom%3Aid=12',
  1075. protocol: 'https:',
  1076. hostname: 'cdpn.io',
  1077. hash: '',
  1078. search: '?custom%3Aid=12',
  1079. pathname: '/test',
  1080. query: {
  1081. 'custom:id': '12'
  1082. }
  1083. }
  1084. };
  1085. Object.keys(formatTests).forEach(function (u) {
  1086. test('format(' + u + ')', function () {
  1087. var expect = formatTests[u].href;
  1088. delete formatTests[u].href;
  1089. var actual = url.format(u);
  1090. var actualObj = url.format(formatTests[u]);
  1091. assert.equal(actual, expect, 'wonky format(' + u + ') == ' + expect + '\nactual:' + actual);
  1092. assert.equal(actualObj, expect, 'wonky format(' + JSON.stringify(formatTests[u]) + ') == ' + expect + '\nactual: ' + actualObj);
  1093. });
  1094. });
  1095. /*
  1096. *[from, path, expected]
  1097. */
  1098. var relativeTests = [
  1099. [
  1100. '/foo/bar/baz', 'quux', '/foo/bar/quux'
  1101. ],
  1102. [
  1103. '/foo/bar/baz', 'quux/asdf', '/foo/bar/quux/asdf'
  1104. ],
  1105. [
  1106. '/foo/bar/baz', 'quux/baz', '/foo/bar/quux/baz'
  1107. ],
  1108. [
  1109. '/foo/bar/baz', '../quux/baz', '/foo/quux/baz'
  1110. ],
  1111. [
  1112. '/foo/bar/baz', '/bar', '/bar'
  1113. ],
  1114. [
  1115. '/foo/bar/baz/', 'quux', '/foo/bar/baz/quux'
  1116. ],
  1117. [
  1118. '/foo/bar/baz/', 'quux/baz', '/foo/bar/baz/quux/baz'
  1119. ],
  1120. [
  1121. '/foo/bar/baz', '../../../../../../../../quux/baz', '/quux/baz'
  1122. ],
  1123. [
  1124. '/foo/bar/baz', '../../../../../../../quux/baz', '/quux/baz'
  1125. ],
  1126. [
  1127. '/foo', '.', '/'
  1128. ],
  1129. [
  1130. '/foo', '..', '/'
  1131. ],
  1132. [
  1133. '/foo/', '.', '/foo/'
  1134. ],
  1135. [
  1136. '/foo/', '..', '/'
  1137. ],
  1138. [
  1139. '/foo/bar', '.', '/foo/'
  1140. ],
  1141. [
  1142. '/foo/bar', '..', '/'
  1143. ],
  1144. [
  1145. '/foo/bar/', '.', '/foo/bar/'
  1146. ],
  1147. [
  1148. '/foo/bar/', '..', '/foo/'
  1149. ],
  1150. [
  1151. 'foo/bar', '../../../baz', '../../baz'
  1152. ],
  1153. [
  1154. 'foo/bar/', '../../../baz', '../baz'
  1155. ],
  1156. [
  1157. 'http://example.com/b//c//d;p?q#blarg', 'https:#hash2', 'https:///#hash2'
  1158. ],
  1159. [
  1160. 'http://example.com/b//c//d;p?q#blarg',
  1161. 'https:/p/a/t/h?s#hash2',
  1162. 'https://p/a/t/h?s#hash2'
  1163. ],
  1164. [
  1165. 'http://example.com/b//c//d;p?q#blarg',
  1166. 'https://u:p@h.com/p/a/t/h?s#hash2',
  1167. 'https://u:p@h.com/p/a/t/h?s#hash2'
  1168. ],
  1169. [
  1170. 'http://example.com/b//c//d;p?q#blarg',
  1171. 'https:/a/b/c/d',
  1172. 'https://a/b/c/d'
  1173. ],
  1174. [
  1175. 'http://example.com/b//c//d;p?q#blarg',
  1176. 'http:#hash2',
  1177. 'http://example.com/b//c//d;p?q#hash2'
  1178. ],
  1179. [
  1180. 'http://example.com/b//c//d;p?q#blarg',
  1181. 'http:/p/a/t/h?s#hash2',
  1182. 'http://example.com/p/a/t/h?s#hash2'
  1183. ],
  1184. [
  1185. 'http://example.com/b//c//d;p?q#blarg',
  1186. 'http://u:p@h.com/p/a/t/h?s#hash2',
  1187. 'http://u:p@h.com/p/a/t/h?s#hash2'
  1188. ],
  1189. [
  1190. 'http://example.com/b//c//d;p?q#blarg',
  1191. 'http:/a/b/c/d',
  1192. 'http://example.com/a/b/c/d'
  1193. ],
  1194. [
  1195. '/foo/bar/baz', '/../etc/passwd', '/etc/passwd'
  1196. ]
  1197. ];
  1198. relativeTests.forEach(function (relativeTest) {
  1199. test('resolve(' + [relativeTest[0], relativeTest[1]] + ')', function () {
  1200. var a = url.resolve(relativeTest[0], relativeTest[1]),
  1201. e = relativeTest[2];
  1202. assert.equal(a, e, 'resolve(' + [relativeTest[0], relativeTest[1]] + ') == ' + e + '\n actual=' + a);
  1203. });
  1204. });
  1205. // https://github.com/joyent/node/issues/568
  1206. [
  1207. undefined,
  1208. null,
  1209. true,
  1210. false,
  1211. 0.0,
  1212. 0,
  1213. [],
  1214. {}
  1215. ].forEach(function (val) {
  1216. test('parse(' + val + ')', function () {
  1217. assert['throws'](function () { url.parse(val); }, TypeError);
  1218. });
  1219. });
  1220. /*
  1221. *
  1222. * Tests below taken from Chiron
  1223. * http://code.google.com/p/chironjs/source/browse/trunk/src/test/http/url.js
  1224. *
  1225. * Copyright (c) 2002-2008 Kris Kowal <http://cixar.com/~kris.kowal>
  1226. * used with permission under MIT License
  1227. *
  1228. * Changes marked with @isaacs
  1229. */
  1230. var bases = [
  1231. 'http://a/b/c/d;p?q',
  1232. 'http://a/b/c/d;p?q=1/2',
  1233. 'http://a/b/c/d;p=1/2?q',
  1234. 'fred:///s//a/b/c',
  1235. 'http:///s//a/b/c'
  1236. ];
  1237. // [to, from, result]
  1238. var relativeTests2 = [
  1239. // http://lists.w3.org/Archives/Public/uri/2004Feb/0114.html
  1240. [
  1241. '../c', 'foo:a/b', 'foo:c'
  1242. ],
  1243. [
  1244. 'foo:.', 'foo:a', 'foo:'
  1245. ],
  1246. [
  1247. '/foo/../../../bar', 'zz:abc', 'zz:/bar'
  1248. ],
  1249. [
  1250. '/foo/../bar', 'zz:abc', 'zz:/bar'
  1251. ],
  1252. // @isaacs Disagree. Not how web browsers resolve this.
  1253. [
  1254. 'foo/../../../bar', 'zz:abc', 'zz:bar'
  1255. ],
  1256. // ['foo/../../../bar', 'zz:abc', 'zz:../../bar'], // @isaacs Added
  1257. [
  1258. 'foo/../bar', 'zz:abc', 'zz:bar'
  1259. ],
  1260. [
  1261. 'zz:.', 'zz:abc', 'zz:'
  1262. ],
  1263. [
  1264. '/.', bases[0], 'http://a/'
  1265. ],
  1266. [
  1267. '/.foo', bases[0], 'http://a/.foo'
  1268. ],
  1269. [
  1270. '.foo', bases[0], 'http://a/b/c/.foo'
  1271. ],
  1272. /*
  1273. * http://gbiv.com/protocols/uri/test/rel_examples1.html
  1274. * examples from RFC 2396
  1275. */
  1276. [
  1277. 'g:h', bases[0], 'g:h'
  1278. ],
  1279. [
  1280. 'g', bases[0], 'http://a/b/c/g'
  1281. ],
  1282. [
  1283. './g', bases[0], 'http://a/b/c/g'
  1284. ],
  1285. [
  1286. 'g/', bases[0], 'http://a/b/c/g/'
  1287. ],
  1288. [
  1289. '/g', bases[0], 'http://a/g'
  1290. ],
  1291. [
  1292. '//g', bases[0], 'http://g/'
  1293. ],
  1294. /*
  1295. * changed with RFC 2396bis
  1296. * ('?y', bases[0], 'http://a/b/c/d;p?y'],
  1297. */
  1298. [
  1299. '?y', bases[0], 'http://a/b/c/d;p?y'
  1300. ],
  1301. [
  1302. 'g?y', bases[0], 'http://a/b/c/g?y'
  1303. ],
  1304. /*
  1305. * changed with RFC 2396bis
  1306. * ('#s', bases[0], CURRENT_DOC_URI + '#s'],
  1307. */
  1308. [
  1309. '#s', bases[0], 'http://a/b/c/d;p?q#s'
  1310. ],
  1311. [
  1312. 'g#s', bases[0], 'http://a/b/c/g#s'
  1313. ],
  1314. [
  1315. 'g?y#s', bases[0], 'http://a/b/c/g?y#s'
  1316. ],
  1317. [
  1318. ';x', bases[0], 'http://a/b/c/;x'
  1319. ],
  1320. [
  1321. 'g;x', bases[0], 'http://a/b/c/g;x'
  1322. ],
  1323. [
  1324. 'g;x?y#s', bases[0], 'http://a/b/c/g;x?y#s'
  1325. ],
  1326. /*
  1327. * changed with RFC 2396bis
  1328. * ('', bases[0], CURRENT_DOC_URI],
  1329. */
  1330. [
  1331. '', bases[0], 'http://a/b/c/d;p?q'
  1332. ],
  1333. [
  1334. '.', bases[0], 'http://a/b/c/'
  1335. ],
  1336. [
  1337. './', bases[0], 'http://a/b/c/'
  1338. ],
  1339. [
  1340. '..', bases[0], 'http://a/b/'
  1341. ],
  1342. [
  1343. '../', bases[0], 'http://a/b/'
  1344. ],
  1345. [
  1346. '../g', bases[0], 'http://a/b/g'
  1347. ],
  1348. [
  1349. '../..', bases[0], 'http://a/'
  1350. ],
  1351. [
  1352. '../../', bases[0], 'http://a/'
  1353. ],
  1354. [
  1355. '../../g', bases[0], 'http://a/g'
  1356. ],
  1357. [
  1358. '../../../g', bases[0], ('http://a/../g', 'http://a/g')
  1359. ],
  1360. [
  1361. '../../../../g', bases[0], ('http://a/../../g', 'http://a/g')
  1362. ],
  1363. /*
  1364. * changed with RFC 2396bis
  1365. * ('/./g', bases[0], 'http://a/./g'],
  1366. */
  1367. [
  1368. '/./g', bases[0], 'http://a/g'
  1369. ],
  1370. /*
  1371. * changed with RFC 2396bis
  1372. * ('/../g', bases[0], 'http://a/../g'],
  1373. */
  1374. [
  1375. '/../g', bases[0], 'http://a/g'
  1376. ],
  1377. [
  1378. 'g.', bases[0], 'http://a/b/c/g.'
  1379. ],
  1380. [
  1381. '.g', bases[0], 'http://a/b/c/.g'
  1382. ],
  1383. [
  1384. 'g..', bases[0], 'http://a/b/c/g..'
  1385. ],
  1386. [
  1387. '..g', bases[0], 'http://a/b/c/..g'
  1388. ],
  1389. [
  1390. './../g', bases[0], 'http://a/b/g'
  1391. ],
  1392. [
  1393. './g/.', bases[0], 'http://a/b/c/g/'
  1394. ],
  1395. [
  1396. 'g/./h', bases[0], 'http://a/b/c/g/h'
  1397. ],
  1398. [
  1399. 'g/../h', bases[0], 'http://a/b/c/h'
  1400. ],
  1401. [
  1402. 'g;x=1/./y', bases[0], 'http://a/b/c/g;x=1/y'
  1403. ],
  1404. [
  1405. 'g;x=1/../y', bases[0], 'http://a/b/c/y'
  1406. ],
  1407. [
  1408. 'g?y/./x', bases[0], 'http://a/b/c/g?y/./x'
  1409. ],
  1410. [
  1411. 'g?y/../x', bases[0], 'http://a/b/c/g?y/../x'
  1412. ],
  1413. [
  1414. 'g#s/./x', bases[0], 'http://a/b/c/g#s/./x'
  1415. ],
  1416. [
  1417. 'g#s/../x', bases[0], 'http://a/b/c/g#s/../x'
  1418. ],
  1419. [
  1420. 'http:g', bases[0], ('http:g', 'http://a/b/c/g')
  1421. ],
  1422. [
  1423. 'http:', bases[0], ('http:', bases[0])
  1424. ],
  1425. // not sure where this one originated
  1426. [
  1427. '/a/b/c/./../../g', bases[0], 'http://a/a/g'
  1428. ],
  1429. /*
  1430. * http://gbiv.com/protocols/uri/test/rel_examples2.html
  1431. * slashes in base URI's query args
  1432. */
  1433. [
  1434. 'g', bases[1], 'http://a/b/c/g'
  1435. ],
  1436. [
  1437. './g', bases[1], 'http://a/b/c/g'
  1438. ],
  1439. [
  1440. 'g/', bases[1], 'http://a/b/c/g/'
  1441. ],
  1442. [
  1443. '/g', bases[1], 'http://a/g'
  1444. ],
  1445. [
  1446. '//g', bases[1], 'http://g/'
  1447. ],
  1448. /*
  1449. * changed in RFC 2396bis
  1450. * ('?y', bases[1], 'http://a/b/c/?y'],
  1451. */
  1452. [
  1453. '?y', bases[1], 'http://a/b/c/d;p?y'
  1454. ],
  1455. [
  1456. 'g?y', bases[1], 'http://a/b/c/g?y'
  1457. ],
  1458. [
  1459. 'g?y/./x', bases[1], 'http://a/b/c/g?y/./x'
  1460. ],
  1461. [
  1462. 'g?y/../x', bases[1], 'http://a/b/c/g?y/../x'
  1463. ],
  1464. [
  1465. 'g#s', bases[1], 'http://a/b/c/g#s'
  1466. ],
  1467. [
  1468. 'g#s/./x', bases[1], 'http://a/b/c/g#s/./x'
  1469. ],
  1470. [
  1471. 'g#s/../x', bases[1], 'http://a/b/c/g#s/../x'
  1472. ],
  1473. [
  1474. './', bases[1], 'http://a/b/c/'
  1475. ],
  1476. [
  1477. '../', bases[1], 'http://a/b/'
  1478. ],
  1479. [
  1480. '../g', bases[1], 'http://a/b/g'
  1481. ],
  1482. [
  1483. '../../', bases[1], 'http://a/'
  1484. ],
  1485. [
  1486. '../../g', bases[1], 'http://a/g'
  1487. ],
  1488. /*
  1489. * http://gbiv.com/protocols/uri/test/rel_examples3.html
  1490. * slashes in path params
  1491. * all of these changed in RFC 2396bis
  1492. */
  1493. [
  1494. 'g', bases[2], 'http://a/b/c/d;p=1/g'
  1495. ],
  1496. [
  1497. './g', bases[2], 'http://a/b/c/d;p=1/g'
  1498. ],
  1499. [
  1500. 'g/', bases[2], 'http://a/b/c/d;p=1/g/'
  1501. ],
  1502. [
  1503. 'g?y', bases[2], 'http://a/b/c/d;p=1/g?y'
  1504. ],
  1505. [
  1506. ';x', bases[2], 'http://a/b/c/d;p=1/;x'
  1507. ],
  1508. [
  1509. 'g;x', bases[2], 'http://a/b/c/d;p=1/g;x'
  1510. ],
  1511. [
  1512. 'g;x=1/./y', bases[2], 'http://a/b/c/d;p=1/g;x=1/y'
  1513. ],
  1514. [
  1515. 'g;x=1/../y', bases[2], 'http://a/b/c/d;p=1/y'
  1516. ],
  1517. [
  1518. './', bases[2], 'http://a/b/c/d;p=1/'
  1519. ],
  1520. [
  1521. '../', bases[2], 'http://a/b/c/'
  1522. ],
  1523. [
  1524. '../g', bases[2], 'http://a/b/c/g'
  1525. ],
  1526. [
  1527. '../../', bases[2], 'http://a/b/'
  1528. ],
  1529. [
  1530. '../../g', bases[2], 'http://a/b/g'
  1531. ],
  1532. /*
  1533. * http://gbiv.com/protocols/uri/test/rel_examples4.html
  1534. * double and triple slash, unknown scheme
  1535. */
  1536. [
  1537. 'g:h', bases[3], 'g:h'
  1538. ],
  1539. [
  1540. 'g', bases[3], 'fred:///s//a/b/g'
  1541. ],
  1542. [
  1543. './g', bases[3], 'fred:///s//a/b/g'
  1544. ],
  1545. [
  1546. 'g/', bases[3], 'fred:///s//a/b/g/'
  1547. ],
  1548. [
  1549. '/g', bases[3], 'fred:///g'
  1550. ], // may change to fred:///s//a/g
  1551. [
  1552. '//g', bases[3], 'fred://g'
  1553. ], // may change to fred:///s//g
  1554. [
  1555. '//g/x', bases[3], 'fred://g/x'
  1556. ], // may change to fred:///s//g/x
  1557. [
  1558. '///g', bases[3], 'fred:///g'
  1559. ],
  1560. [
  1561. './', bases[3], 'fred:///s//a/b/'
  1562. ],
  1563. [
  1564. '../', bases[3], 'fred:///s//a/'
  1565. ],
  1566. [
  1567. '../g', bases[3], 'fred:///s//a/g'
  1568. ],
  1569. [
  1570. '../../', bases[3], 'fred:///s//'
  1571. ],
  1572. [
  1573. '../../g', bases[3], 'fred:///s//g'
  1574. ],
  1575. [
  1576. '../../../g', bases[3], 'fred:///s/g'
  1577. ],
  1578. // may change to fred:///s//a/../../../g
  1579. [
  1580. '../../../../g', bases[3], 'fred:///g'
  1581. ],
  1582. /*
  1583. * http://gbiv.com/protocols/uri/test/rel_examples5.html
  1584. * double and triple slash, well-known scheme
  1585. */
  1586. [
  1587. 'g:h', bases[4], 'g:h'
  1588. ],
  1589. [
  1590. 'g', bases[4], 'http:///s//a/b/g'
  1591. ],
  1592. [
  1593. './g', bases[4], 'http:///s//a/b/g'
  1594. ],
  1595. [
  1596. 'g/', bases[4], 'http:///s//a/b/g/'
  1597. ],
  1598. [
  1599. '/g', bases[4], 'http:///g'
  1600. ], // may change to http:///s//a/g
  1601. [
  1602. '//g', bases[4], 'http://g/'
  1603. ], // may change to http:///s//g
  1604. [
  1605. '//g/x', bases[4], 'http://g/x'
  1606. ], // may change to http:///s//g/x
  1607. [
  1608. '///g', bases[4], 'http:///g'
  1609. ],
  1610. [
  1611. './', bases[4], 'http:///s//a/b/'
  1612. ],
  1613. [
  1614. '../', bases[4], 'http:///s//a/'
  1615. ],
  1616. [
  1617. '../g', bases[4], 'http:///s//a/g'
  1618. ],
  1619. [
  1620. '../../', bases[4], 'http:///s//'
  1621. ],
  1622. [
  1623. '../../g', bases[4], 'http:///s//g'
  1624. ],
  1625. // may change to http:///s//a/../../g
  1626. [
  1627. '../../../g', bases[4], 'http:///s/g'
  1628. ],
  1629. // may change to http:///s//a/../../../g
  1630. [
  1631. '../../../../g', bases[4], 'http:///g'
  1632. ],
  1633. // from Dan Connelly's tests in http://www.w3.org/2000/10/swap/uripath.py
  1634. [
  1635. 'bar:abc', 'foo:xyz', 'bar:abc'
  1636. ],
  1637. [
  1638. '../abc', 'http://example/x/y/z', 'http://example/x/abc'
  1639. ],
  1640. [
  1641. 'http://example/x/abc', 'http://example2/x/y/z', 'http://example/x/abc'
  1642. ],
  1643. [
  1644. '../r', 'http://ex/x/y/z', 'http://ex/x/r'
  1645. ],
  1646. [
  1647. 'q/r', 'http://ex/x/y', 'http://ex/x/q/r'
  1648. ],
  1649. [
  1650. 'q/r#s', 'http://ex/x/y', 'http://ex/x/q/r#s'
  1651. ],
  1652. [
  1653. 'q/r#s/t', 'http://ex/x/y', 'http://ex/x/q/r#s/t'
  1654. ],
  1655. [
  1656. 'ftp://ex/x/q/r', 'http://ex/x/y', 'ftp://ex/x/q/r'
  1657. ],
  1658. [
  1659. '', 'http://ex/x/y', 'http://ex/x/y'
  1660. ],
  1661. [
  1662. '', 'http://ex/x/y/', 'http://ex/x/y/'
  1663. ],
  1664. [
  1665. '', 'http://ex/x/y/pdq', 'http://ex/x/y/pdq'
  1666. ],
  1667. [
  1668. 'z/', 'http://ex/x/y/', 'http://ex/x/y/z/'
  1669. ],
  1670. [
  1671. '#Animal',
  1672. 'file:/swap/test/animal.rdf',
  1673. 'file:/swap/test/animal.rdf#Animal'
  1674. ],
  1675. [
  1676. '../abc', 'file:/e/x/y/z', 'file:/e/x/abc'
  1677. ],
  1678. [
  1679. '/example/x/abc', 'file:/example2/x/y/z', 'file:/example/x/abc'
  1680. ],
  1681. [
  1682. '../r', 'file:/ex/x/y/z', 'file:/ex/x/r'
  1683. ],
  1684. [
  1685. '/r', 'file:/ex/x/y/z', 'file:/r'
  1686. ],
  1687. [
  1688. 'q/r', 'file:/ex/x/y', 'file:/ex/x/q/r'
  1689. ],
  1690. [
  1691. 'q/r#s', 'file:/ex/x/y', 'file:/ex/x/q/r#s'
  1692. ],
  1693. [
  1694. 'q/r#', 'file:/ex/x/y', 'file:/ex/x/q/r#'
  1695. ],
  1696. [
  1697. 'q/r#s/t', 'file:/ex/x/y', 'file:/ex/x/q/r#s/t'
  1698. ],
  1699. [
  1700. 'ftp://ex/x/q/r', 'file:/ex/x/y', 'ftp://ex/x/q/r'
  1701. ],
  1702. [
  1703. '', 'file:/ex/x/y', 'file:/ex/x/y'
  1704. ],
  1705. [
  1706. '', 'file:/ex/x/y/', 'file:/ex/x/y/'
  1707. ],
  1708. [
  1709. '', 'file:/ex/x/y/pdq', 'file:/ex/x/y/pdq'
  1710. ],
  1711. [
  1712. 'z/', 'file:/ex/x/y/', 'file:/ex/x/y/z/'
  1713. ],
  1714. [
  1715. 'file://meetings.example.com/cal#m1',
  1716. 'file:/devel/WWW/2000/10/swap/test/reluri-1.n3',
  1717. 'file://meetings.example.com/cal#m1'
  1718. ],
  1719. [
  1720. 'file://meetings.example.com/cal#m1',
  1721. 'file:/home/connolly/w3ccvs/WWW/2000/10/swap/test/reluri-1.n3',
  1722. 'file://meetings.example.com/cal#m1'
  1723. ],
  1724. [
  1725. './#blort', 'file:/some/dir/foo', 'file:/some/dir/#blort'
  1726. ],
  1727. [
  1728. './#', 'file:/some/dir/foo', 'file:/some/dir/#'
  1729. ],
  1730. // Ryan Lee
  1731. [
  1732. './', 'http://example/x/abc.efg', 'http://example/x/'
  1733. ],
  1734. /*
  1735. * Graham Klyne's tests
  1736. * http://www.ninebynine.org/Software/HaskellUtils/Network/UriTest.xls
  1737. * 01-31 are from Connelly's cases
  1738. */
  1739. // 32-49
  1740. [
  1741. './q:r', 'http://ex/x/y', 'http://ex/x/q:r'
  1742. ],
  1743. [
  1744. './p=q:r', 'http://ex/x/y', 'http://ex/x/p=q:r'
  1745. ],
  1746. [
  1747. '?pp/rr', 'http://ex/x/y?pp/qq', 'http://ex/x/y?pp/rr'
  1748. ],
  1749. [
  1750. 'y/z', 'http://ex/x/y?pp/qq', 'http://ex/x/y/z'
  1751. ],
  1752. [
  1753. 'local/qual@domain.org#frag',
  1754. 'mailto:local',
  1755. 'mailto:local/qual@domain.org#frag'
  1756. ],
  1757. [
  1758. 'more/qual2@domain2.org#frag',
  1759. 'mailto:local/qual1@domain1.org',
  1760. 'mailto:local/more/qual2@domain2.org#frag'
  1761. ],
  1762. [
  1763. 'y?q', 'http://ex/x/y?q', 'http://ex/x/y?q'
  1764. ],
  1765. [
  1766. '/x/y?q', 'http://ex?p', 'http://ex/x/y?q'
  1767. ],
  1768. [
  1769. 'c/d', 'foo:a/b', 'foo:a/c/d'
  1770. ],
  1771. [
  1772. '/c/d', 'foo:a/b', 'foo:/c/d'
  1773. ],
  1774. [
  1775. '', 'foo:a/b?c#d', 'foo:a/b?c'
  1776. ],
  1777. [
  1778. 'b/c', 'foo:a', 'foo:b/c'
  1779. ],
  1780. [
  1781. '../b/c', 'foo:/a/y/z', 'foo:/a/b/c'
  1782. ],
  1783. [
  1784. './b/c', 'foo:a', 'foo:b/c'
  1785. ],
  1786. [
  1787. '/./b/c', 'foo:a', 'foo:/b/c'
  1788. ],
  1789. [
  1790. '../../d', 'foo://a//b/c', 'foo://a/d'
  1791. ],
  1792. [
  1793. '.', 'foo:a', 'foo:'
  1794. ],
  1795. [
  1796. '..', 'foo:a', 'foo:'
  1797. ],
  1798. /*
  1799. * 50-57[cf. TimBL comments --
  1800. * http://lists.w3.org/Archives/Public/uri/2003Feb/0028.html,
  1801. * http://lists.w3.org/Archives/Public/uri/2003Jan/0008.html)
  1802. */
  1803. [
  1804. 'abc', 'http://example/x/y%2Fz', 'http://example/x/abc'
  1805. ],
  1806. [
  1807. '../../x%2Fabc', 'http://example/a/x/y/z', 'http://example/a/x%2Fabc'
  1808. ],
  1809. [
  1810. '../x%2Fabc', 'http://example/a/x/y%2Fz', 'http://example/a/x%2Fabc'
  1811. ],
  1812. [
  1813. 'abc', 'http://example/x%2Fy/z', 'http://example/x%2Fy/abc'
  1814. ],
  1815. [
  1816. 'q%3Ar', 'http://ex/x/y', 'http://ex/x/q%3Ar'
  1817. ],
  1818. [
  1819. '/x%2Fabc', 'http://example/x/y%2Fz', 'http://example/x%2Fabc'
  1820. ],
  1821. [
  1822. '/x%2Fabc', 'http://example/x/y/z', 'http://example/x%2Fabc'
  1823. ],
  1824. [
  1825. '/x%2Fabc', 'http://example/x/y%2Fz', 'http://example/x%2Fabc'
  1826. ],
  1827. // 70-77
  1828. [
  1829. 'local2@domain2', 'mailto:local1@domain1?query1', 'mailto:local2@domain2'
  1830. ],
  1831. [
  1832. 'local2@domain2?query2',
  1833. 'mailto:local1@domain1',
  1834. 'mailto:local2@domain2?query2'
  1835. ],
  1836. [
  1837. 'local2@domain2?query2',
  1838. 'mailto:local1@domain1?query1',
  1839. 'mailto:local2@domain2?query2'
  1840. ],
  1841. [
  1842. '?query2', 'mailto:local@domain?query1', 'mailto:local@domain?query2'
  1843. ],
  1844. [
  1845. 'local@domain?query2', 'mailto:?query1', 'mailto:local@domain?query2'
  1846. ],
  1847. [
  1848. '?query2', 'mailto:local@domain?query1', 'mailto:local@domain?query2'
  1849. ],
  1850. [
  1851. 'http://example/a/b?c/../d', 'foo:bar', 'http://example/a/b?c/../d'
  1852. ],
  1853. [
  1854. 'http://example/a/b#c/../d', 'foo:bar', 'http://example/a/b#c/../d'
  1855. ],
  1856. /*
  1857. * 82-88
  1858. * @isaacs Disagree. Not how browsers do it.
  1859. * ['http:this', 'http://example.org/base/uri', 'http:this'],
  1860. * @isaacs Added
  1861. */
  1862. [
  1863. 'http:this', 'http://example.org/base/uri', 'http://example.org/base/this'
  1864. ],
  1865. [
  1866. 'http:this', 'http:base', 'http:this'
  1867. ],
  1868. [
  1869. './/g', 'f:/a', 'f://g'
  1870. ],
  1871. [
  1872. 'b/c//d/e', 'f://example.org/base/a', 'f://example.org/base/b/c//d/e'
  1873. ],
  1874. [
  1875. 'm2@example.ord/c2@example.org',
  1876. 'mid:m@example.ord/c@example.org',
  1877. 'mid:m@example.ord/m2@example.ord/c2@example.org'
  1878. ],
  1879. [
  1880. 'mini1.xml',
  1881. 'file:///C:/DEV/Haskell/lib/HXmlToolbox-3.01/examples/',
  1882. 'file:///C:/DEV/Haskell/lib/HXmlToolbox-3.01/examples/mini1.xml'
  1883. ],
  1884. [
  1885. '../b/c', 'foo:a/y/z', 'foo:a/b/c'
  1886. ],
  1887. // changeing auth
  1888. [
  1889. 'http://diff:auth@www.example.com',
  1890. 'http://asdf:qwer@www.example.com',
  1891. 'http://diff:auth@www.example.com/'
  1892. ]
  1893. ];
  1894. relativeTests2.forEach(function (relativeTest) {
  1895. test('resolve(' + [relativeTest[1], relativeTest[0]] + ')', function () {
  1896. var a = url.resolve(relativeTest[1], relativeTest[0]),
  1897. e = relativeTest[2];
  1898. assert.equal(a, e, 'resolve(' + [relativeTest[1], relativeTest[0]] + ') == ' + e + '\n actual=' + a);
  1899. });
  1900. });
  1901. /*
  1902. * if format and parse are inverse operations then
  1903. * resolveObject(parse(x), y) == parse(resolve(x, y))
  1904. */
  1905. // host and hostname are special, in this case a '' value is important
  1906. /* eslint no-unused-vars: 1 */
  1907. var emptyIsImportant = { host: true, hostname: '' };
  1908. // format: [from, path, expected]
  1909. relativeTests.forEach(function (relativeTest) {
  1910. test('resolveObject(' + [relativeTest[0], relativeTest[1]] + ')', function () {
  1911. var actual = url.resolveObject(url.parse(relativeTest[0]), relativeTest[1]);
  1912. var expected = url.parse(relativeTest[2]);
  1913. assert.deepEqual(actual, expected);
  1914. expected = relativeTest[2];
  1915. actual = url.format(actual);
  1916. assert.equal(actual, expected, 'format(' + actual + ') == ' + expected + '\nactual:' + actual);
  1917. });
  1918. });
  1919. test('format with querystring', function () {
  1920. var obj = { protocol: 'https:', host: 'google.com', pathname: 'test', query: { message: ['value1', 'value2'], 'custom:id': 12 } };
  1921. var actual = url.format(obj);
  1922. var expected = nodeURL.format(obj);
  1923. assert.equal(actual, expected, 'format(' + actual + ') == ' + expected + '\nactual:' + actual);
  1924. });
  1925. /*
  1926. * format: [to, from, result]
  1927. * the test: ['.//g', 'f:/a', 'f://g'] is a fundamental problem
  1928. * url.parse('f:/a') does not have a host
  1929. * url.resolve('f:/a', './/g') does not have a host because you have moved
  1930. * down to the g directory. i.e. f: //g, however when this url is parsed
  1931. * f:// will indicate that the host is g which is not the case.
  1932. * it is unclear to me how to keep this information from being lost
  1933. * it may be that a pathname of ////g should collapse to /g but this seems
  1934. * to be a lot of work for an edge case. Right now I remove the test
  1935. */
  1936. if (relativeTests2[181][0] === './/g' && relativeTests2[181][1] === 'f:/a' && relativeTests2[181][2] === 'f://g') {
  1937. relativeTests2.splice(181, 1);
  1938. }
  1939. relativeTests2.forEach(function (relativeTest) {
  1940. test('resolveObject(' + [relativeTest[1], relativeTest[0]] + ')', function () {
  1941. var actual = url.resolveObject(url.parse(relativeTest[1]), relativeTest[0]),
  1942. expected = url.parse(relativeTest[2]);
  1943. assert.deepEqual(actual, expected);
  1944. var expected = relativeTest[2],
  1945. actual = url.format(actual);
  1946. assert.equal(actual, expected, 'format(' + relativeTest[1] + ') == ' + expected + '\nactual:' + actual);
  1947. });
  1948. });