You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

912 lines
40 KiB

1 month ago
  1. 'use strict'
  2. const test = require('tape')
  3. const URI = require('../index')
  4. /**
  5. * URI.js
  6. *
  7. * @fileoverview An RFC 3986 compliant, scheme extendable URI parsing/normalizing/resolving/serializing library for JavaScript.
  8. * @author <a href="mailto:gary.court@gmail.com">Gary Court</a>
  9. * @see http://github.com/garycourt/uri-js
  10. */
  11. /**
  12. * Copyright 2011 Gary Court. All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without modification, are
  15. * permitted provided that the following conditions are met:
  16. *
  17. * 1. Redistributions of source code must retain the above copyright notice, this list of
  18. * conditions and the following disclaimer.
  19. *
  20. * 2. Redistributions in binary form must reproduce the above copyright notice, this list
  21. * of conditions and the following disclaimer in the documentation and/or other materials
  22. * provided with the distribution.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY GARY COURT ``AS IS'' AND ANY EXPRESS OR IMPLIED
  25. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  26. * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARY COURT OR
  27. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  29. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  31. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  32. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. * The views and conclusions contained in the software and documentation are those of the
  35. * authors and should not be interpreted as representing official policies, either expressed
  36. * or implied, of Gary Court.
  37. */
  38. test('Acquire URI', (t) => {
  39. t.ok(URI)
  40. t.end()
  41. })
  42. test('URI Parsing', (t) => {
  43. let components
  44. // scheme
  45. components = URI.parse('uri:')
  46. t.equal(components.error, undefined, 'scheme errors')
  47. t.equal(components.scheme, 'uri', 'scheme')
  48. t.equal(components.userinfo, undefined, 'userinfo')
  49. t.equal(components.host, undefined, 'host')
  50. t.equal(components.port, undefined, 'port')
  51. t.equal(components.path, '', 'path')
  52. t.equal(components.query, undefined, 'query')
  53. t.equal(components.fragment, undefined, 'fragment')
  54. // userinfo
  55. components = URI.parse('//@')
  56. t.equal(components.error, undefined, 'userinfo errors')
  57. t.equal(components.scheme, undefined, 'scheme')
  58. t.equal(components.userinfo, '', 'userinfo')
  59. t.equal(components.host, '', 'host')
  60. t.equal(components.port, undefined, 'port')
  61. t.equal(components.path, '', 'path')
  62. t.equal(components.query, undefined, 'query')
  63. t.equal(components.fragment, undefined, 'fragment')
  64. // host
  65. components = URI.parse('//')
  66. t.equal(components.error, undefined, 'host errors')
  67. t.equal(components.scheme, undefined, 'scheme')
  68. t.equal(components.userinfo, undefined, 'userinfo')
  69. t.equal(components.host, '', 'host')
  70. t.equal(components.port, undefined, 'port')
  71. t.equal(components.path, '', 'path')
  72. t.equal(components.query, undefined, 'query')
  73. t.equal(components.fragment, undefined, 'fragment')
  74. // port
  75. components = URI.parse('//:')
  76. t.equal(components.error, undefined, 'port errors')
  77. t.equal(components.scheme, undefined, 'scheme')
  78. t.equal(components.userinfo, undefined, 'userinfo')
  79. t.equal(components.host, '', 'host')
  80. t.equal(components.port, '', 'port')
  81. t.equal(components.path, '', 'path')
  82. t.equal(components.query, undefined, 'query')
  83. t.equal(components.fragment, undefined, 'fragment')
  84. // path
  85. components = URI.parse('')
  86. t.equal(components.error, undefined, 'path errors')
  87. t.equal(components.scheme, undefined, 'scheme')
  88. t.equal(components.userinfo, undefined, 'userinfo')
  89. t.equal(components.host, undefined, 'host')
  90. t.equal(components.port, undefined, 'port')
  91. t.equal(components.path, '', 'path')
  92. t.equal(components.query, undefined, 'query')
  93. t.equal(components.fragment, undefined, 'fragment')
  94. // query
  95. components = URI.parse('?')
  96. t.equal(components.error, undefined, 'query errors')
  97. t.equal(components.scheme, undefined, 'scheme')
  98. t.equal(components.userinfo, undefined, 'userinfo')
  99. t.equal(components.host, undefined, 'host')
  100. t.equal(components.port, undefined, 'port')
  101. t.equal(components.path, '', 'path')
  102. t.equal(components.query, '', 'query')
  103. t.equal(components.fragment, undefined, 'fragment')
  104. // fragment
  105. components = URI.parse('#')
  106. t.equal(components.error, undefined, 'fragment errors')
  107. t.equal(components.scheme, undefined, 'scheme')
  108. t.equal(components.userinfo, undefined, 'userinfo')
  109. t.equal(components.host, undefined, 'host')
  110. t.equal(components.port, undefined, 'port')
  111. t.equal(components.path, '', 'path')
  112. t.equal(components.query, undefined, 'query')
  113. t.equal(components.fragment, '', 'fragment')
  114. // fragment with character tabulation
  115. components = URI.parse('#\t')
  116. t.equal(components.error, undefined, 'path errors')
  117. t.equal(components.scheme, undefined, 'scheme')
  118. t.equal(components.userinfo, undefined, 'userinfo')
  119. t.equal(components.host, undefined, 'host')
  120. t.equal(components.port, undefined, 'port')
  121. t.equal(components.path, '', 'path')
  122. t.equal(components.query, undefined, 'query')
  123. t.equal(components.fragment, '%09', 'fragment')
  124. // fragment with line feed
  125. components = URI.parse('#\n')
  126. t.equal(components.error, undefined, 'path errors')
  127. t.equal(components.scheme, undefined, 'scheme')
  128. t.equal(components.userinfo, undefined, 'userinfo')
  129. t.equal(components.host, undefined, 'host')
  130. t.equal(components.port, undefined, 'port')
  131. t.equal(components.path, '', 'path')
  132. t.equal(components.query, undefined, 'query')
  133. t.equal(components.fragment, '%0A', 'fragment')
  134. // fragment with line tabulation
  135. components = URI.parse('#\v')
  136. t.equal(components.error, undefined, 'path errors')
  137. t.equal(components.scheme, undefined, 'scheme')
  138. t.equal(components.userinfo, undefined, 'userinfo')
  139. t.equal(components.host, undefined, 'host')
  140. t.equal(components.port, undefined, 'port')
  141. t.equal(components.path, '', 'path')
  142. t.equal(components.query, undefined, 'query')
  143. t.equal(components.fragment, '%0B', 'fragment')
  144. // fragment with form feed
  145. components = URI.parse('#\f')
  146. t.equal(components.error, undefined, 'path errors')
  147. t.equal(components.scheme, undefined, 'scheme')
  148. t.equal(components.userinfo, undefined, 'userinfo')
  149. t.equal(components.host, undefined, 'host')
  150. t.equal(components.port, undefined, 'port')
  151. t.equal(components.path, '', 'path')
  152. t.equal(components.query, undefined, 'query')
  153. t.equal(components.fragment, '%0C', 'fragment')
  154. // fragment with carriage return
  155. components = URI.parse('#\r')
  156. t.equal(components.error, undefined, 'path errors')
  157. t.equal(components.scheme, undefined, 'scheme')
  158. t.equal(components.userinfo, undefined, 'userinfo')
  159. t.equal(components.host, undefined, 'host')
  160. t.equal(components.port, undefined, 'port')
  161. t.equal(components.path, '', 'path')
  162. t.equal(components.query, undefined, 'query')
  163. t.equal(components.fragment, '%0D', 'fragment')
  164. // all
  165. components = URI.parse('uri://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body')
  166. t.equal(components.error, undefined, 'all errors')
  167. t.equal(components.scheme, 'uri', 'scheme')
  168. t.equal(components.userinfo, 'user:pass', 'userinfo')
  169. t.equal(components.host, 'example.com', 'host')
  170. t.equal(components.port, 123, 'port')
  171. t.equal(components.path, '/one/two.three', 'path')
  172. t.equal(components.query, 'q1=a1&q2=a2', 'query')
  173. t.equal(components.fragment, 'body', 'fragment')
  174. // IPv4address
  175. components = URI.parse('//10.10.10.10')
  176. t.equal(components.error, undefined, 'IPv4address errors')
  177. t.equal(components.scheme, undefined, 'scheme')
  178. t.equal(components.userinfo, undefined, 'userinfo')
  179. t.equal(components.host, '10.10.10.10', 'host')
  180. t.equal(components.port, undefined, 'port')
  181. t.equal(components.path, '', 'path')
  182. t.equal(components.query, undefined, 'query')
  183. t.equal(components.fragment, undefined, 'fragment')
  184. // IPv6address
  185. components = URI.parse('//[2001:db8::7]')
  186. t.equal(components.error, undefined, 'IPv4address errors')
  187. t.equal(components.scheme, undefined, 'scheme')
  188. t.equal(components.userinfo, undefined, 'userinfo')
  189. t.equal(components.host, '2001:db8::7', 'host')
  190. t.equal(components.port, undefined, 'port')
  191. t.equal(components.path, '', 'path')
  192. t.equal(components.query, undefined, 'query')
  193. t.equal(components.fragment, undefined, 'fragment')
  194. // mixed IPv4address & IPv6address
  195. components = URI.parse('//[::ffff:129.144.52.38]')
  196. t.equal(components.error, undefined, 'IPv4address errors')
  197. t.equal(components.scheme, undefined, 'scheme')
  198. t.equal(components.userinfo, undefined, 'userinfo')
  199. t.equal(components.host, '::ffff:129.144.52.38', 'host')
  200. t.equal(components.port, undefined, 'port')
  201. t.equal(components.path, '', 'path')
  202. t.equal(components.query, undefined, 'query')
  203. t.equal(components.fragment, undefined, 'fragment')
  204. // mixed IPv4address & reg-name, example from terion-name (https://github.com/garycourt/uri-js/issues/4)
  205. components = URI.parse('uri://10.10.10.10.example.com/en/process')
  206. t.equal(components.error, undefined, 'mixed errors')
  207. t.equal(components.scheme, 'uri', 'scheme')
  208. t.equal(components.userinfo, undefined, 'userinfo')
  209. t.equal(components.host, '10.10.10.10.example.com', 'host')
  210. t.equal(components.port, undefined, 'port')
  211. t.equal(components.path, '/en/process', 'path')
  212. t.equal(components.query, undefined, 'query')
  213. t.equal(components.fragment, undefined, 'fragment')
  214. // IPv6address, example from bkw (https://github.com/garycourt/uri-js/pull/16)
  215. components = URI.parse('//[2606:2800:220:1:248:1893:25c8:1946]/test')
  216. t.equal(components.error, undefined, 'IPv6address errors')
  217. t.equal(components.scheme, undefined, 'scheme')
  218. t.equal(components.userinfo, undefined, 'userinfo')
  219. t.equal(components.host, '2606:2800:220:1:248:1893:25c8:1946', 'host')
  220. t.equal(components.port, undefined, 'port')
  221. t.equal(components.path, '/test', 'path')
  222. t.equal(components.query, undefined, 'query')
  223. t.equal(components.fragment, undefined, 'fragment')
  224. // IPv6address, example from RFC 5952
  225. components = URI.parse('//[2001:db8::1]:80')
  226. t.equal(components.error, undefined, 'IPv6address errors')
  227. t.equal(components.scheme, undefined, 'scheme')
  228. t.equal(components.userinfo, undefined, 'userinfo')
  229. t.equal(components.host, '2001:db8::1', 'host')
  230. t.equal(components.port, 80, 'port')
  231. t.equal(components.path, '', 'path')
  232. t.equal(components.query, undefined, 'query')
  233. t.equal(components.fragment, undefined, 'fragment')
  234. // IPv6address with zone identifier, RFC 6874
  235. components = URI.parse('//[fe80::a%25en1]')
  236. t.equal(components.error, undefined, 'IPv4address errors')
  237. t.equal(components.scheme, undefined, 'scheme')
  238. t.equal(components.userinfo, undefined, 'userinfo')
  239. t.equal(components.host, 'fe80::a%en1', 'host')
  240. t.equal(components.port, undefined, 'port')
  241. t.equal(components.path, '', 'path')
  242. t.equal(components.query, undefined, 'query')
  243. t.equal(components.fragment, undefined, 'fragment')
  244. // IPv6address with an unescaped interface specifier, example from pekkanikander (https://github.com/garycourt/uri-js/pull/22)
  245. components = URI.parse('//[2001:db8::7%en0]')
  246. t.equal(components.error, undefined, 'IPv6address interface errors')
  247. t.equal(components.scheme, undefined, 'scheme')
  248. t.equal(components.userinfo, undefined, 'userinfo')
  249. t.equal(components.host, '2001:db8::7%en0', 'host')
  250. t.equal(components.port, undefined, 'port')
  251. t.equal(components.path, '', 'path')
  252. t.equal(components.query, undefined, 'query')
  253. t.equal(components.fragment, undefined, 'fragment')
  254. t.end()
  255. })
  256. test('URI Serialization', (t) => {
  257. let components = {
  258. scheme: undefined,
  259. userinfo: undefined,
  260. host: undefined,
  261. port: undefined,
  262. path: undefined,
  263. query: undefined,
  264. fragment: undefined
  265. }
  266. t.equal(URI.serialize(components), '', 'Undefined Components')
  267. components = {
  268. scheme: '',
  269. userinfo: '',
  270. host: '',
  271. port: 0,
  272. path: '',
  273. query: '',
  274. fragment: ''
  275. }
  276. t.equal(URI.serialize(components), '//@:0?#', 'Empty Components')
  277. components = {
  278. scheme: 'uri',
  279. userinfo: 'foo:bar',
  280. host: 'example.com',
  281. port: 1,
  282. path: 'path',
  283. query: 'query',
  284. fragment: 'fragment'
  285. }
  286. t.equal(URI.serialize(components), 'uri://foo:bar@example.com:1/path?query#fragment', 'All Components')
  287. components = {
  288. scheme: 'uri',
  289. host: 'example.com',
  290. port: '9000'
  291. }
  292. t.equal(URI.serialize(components), 'uri://example.com:9000', 'String port')
  293. t.equal(URI.serialize({ path: '//path' }), '/%2Fpath', 'Double slash path')
  294. t.equal(URI.serialize({ path: 'foo:bar' }), 'foo%3Abar', 'Colon path')
  295. t.equal(URI.serialize({ path: '?query' }), '%3Fquery', 'Query path')
  296. // mixed IPv4address & reg-name, example from terion-name (https://github.com/garycourt/uri-js/issues/4)
  297. t.equal(URI.serialize({ host: '10.10.10.10.example.com' }), '//10.10.10.10.example.com', 'Mixed IPv4address & reg-name')
  298. // IPv6address
  299. t.equal(URI.serialize({ host: '2001:db8::7' }), '//[2001:db8::7]', 'IPv6 Host')
  300. t.equal(URI.serialize({ host: '::ffff:129.144.52.38' }), '//[::ffff:129.144.52.38]', 'IPv6 Mixed Host')
  301. t.equal(URI.serialize({ host: '2606:2800:220:1:248:1893:25c8:1946' }), '//[2606:2800:220:1:248:1893:25c8:1946]', 'IPv6 Full Host')
  302. // IPv6address with zone identifier, RFC 6874
  303. t.equal(URI.serialize({ host: 'fe80::a%en1' }), '//[fe80::a%25en1]', 'IPv6 Zone Unescaped Host')
  304. t.equal(URI.serialize({ host: 'fe80::a%25en1' }), '//[fe80::a%25en1]', 'IPv6 Zone Escaped Host')
  305. t.end()
  306. })
  307. test('URI Resolving', { skip: true }, (t) => {
  308. // normal examples from RFC 3986
  309. const base = 'uri://a/b/c/d;p?q'
  310. t.equal(URI.resolve(base, 'g:h'), 'g:h', 'g:h')
  311. t.equal(URI.resolve(base, 'g'), 'uri://a/b/c/g', 'g')
  312. t.equal(URI.resolve(base, './g'), 'uri://a/b/c/g', './g')
  313. t.equal(URI.resolve(base, 'g/'), 'uri://a/b/c/g/', 'g/')
  314. t.equal(URI.resolve(base, '/g'), 'uri://a/g', '/g')
  315. t.equal(URI.resolve(base, '//g'), 'uri://g', '//g')
  316. t.equal(URI.resolve(base, '?y'), 'uri://a/b/c/d;p?y', '?y')
  317. t.equal(URI.resolve(base, 'g?y'), 'uri://a/b/c/g?y', 'g?y')
  318. t.equal(URI.resolve(base, '#s'), 'uri://a/b/c/d;p?q#s', '#s')
  319. t.equal(URI.resolve(base, 'g#s'), 'uri://a/b/c/g#s', 'g#s')
  320. t.equal(URI.resolve(base, 'g?y#s'), 'uri://a/b/c/g?y#s', 'g?y#s')
  321. t.equal(URI.resolve(base, ';x'), 'uri://a/b/c/;x', ';x')
  322. t.equal(URI.resolve(base, 'g;x'), 'uri://a/b/c/g;x', 'g;x')
  323. t.equal(URI.resolve(base, 'g;x?y#s'), 'uri://a/b/c/g;x?y#s', 'g;x?y#s')
  324. t.equal(URI.resolve(base, ''), 'uri://a/b/c/d;p?q', '')
  325. t.equal(URI.resolve(base, '.'), 'uri://a/b/c/', '.')
  326. t.equal(URI.resolve(base, './'), 'uri://a/b/c/', './')
  327. t.equal(URI.resolve(base, '..'), 'uri://a/b/', '..')
  328. t.equal(URI.resolve(base, '../'), 'uri://a/b/', '../')
  329. t.equal(URI.resolve(base, '../g'), 'uri://a/b/g', '../g')
  330. t.equal(URI.resolve(base, '../..'), 'uri://a/', '../..')
  331. t.equal(URI.resolve(base, '../../'), 'uri://a/', '../../')
  332. t.equal(URI.resolve(base, '../../g'), 'uri://a/g', '../../g')
  333. // abnormal examples from RFC 3986
  334. t.equal(URI.resolve(base, '../../../g'), 'uri://a/g', '../../../g')
  335. t.equal(URI.resolve(base, '../../../../g'), 'uri://a/g', '../../../../g')
  336. t.equal(URI.resolve(base, '/./g'), 'uri://a/g', '/./g')
  337. t.equal(URI.resolve(base, '/../g'), 'uri://a/g', '/../g')
  338. t.equal(URI.resolve(base, 'g.'), 'uri://a/b/c/g.', 'g.')
  339. t.equal(URI.resolve(base, '.g'), 'uri://a/b/c/.g', '.g')
  340. t.equal(URI.resolve(base, 'g..'), 'uri://a/b/c/g..', 'g..')
  341. t.equal(URI.resolve(base, '..g'), 'uri://a/b/c/..g', '..g')
  342. t.equal(URI.resolve(base, './../g'), 'uri://a/b/g', './../g')
  343. t.equal(URI.resolve(base, './g/.'), 'uri://a/b/c/g/', './g/.')
  344. t.equal(URI.resolve(base, 'g/./h'), 'uri://a/b/c/g/h', 'g/./h')
  345. t.equal(URI.resolve(base, 'g/../h'), 'uri://a/b/c/h', 'g/../h')
  346. t.equal(URI.resolve(base, 'g;x=1/./y'), 'uri://a/b/c/g;x=1/y', 'g;x=1/./y')
  347. t.equal(URI.resolve(base, 'g;x=1/../y'), 'uri://a/b/c/y', 'g;x=1/../y')
  348. t.equal(URI.resolve(base, 'g?y/./x'), 'uri://a/b/c/g?y/./x', 'g?y/./x')
  349. t.equal(URI.resolve(base, 'g?y/../x'), 'uri://a/b/c/g?y/../x', 'g?y/../x')
  350. t.equal(URI.resolve(base, 'g#s/./x'), 'uri://a/b/c/g#s/./x', 'g#s/./x')
  351. t.equal(URI.resolve(base, 'g#s/../x'), 'uri://a/b/c/g#s/../x', 'g#s/../x')
  352. t.equal(URI.resolve(base, 'uri:g'), 'uri:g', 'uri:g')
  353. t.equal(URI.resolve(base, 'uri:g', { tolerant: true }), 'uri://a/b/c/g', 'uri:g')
  354. // examples by PAEz
  355. t.equal(URI.resolve('//www.g.com/', '/adf\ngf'), '//www.g.com/adf%0Agf', '/adf\\ngf')
  356. t.equal(URI.resolve('//www.g.com/error\n/bleh/bleh', '..'), '//www.g.com/error%0A/', '//www.g.com/error\\n/bleh/bleh')
  357. t.end()
  358. })
  359. test('URI Normalizing', { skip: true }, (t) => {
  360. // test from RFC 3987
  361. t.equal(URI.normalize('uri://www.example.org/red%09ros\xE9#red'), 'uri://www.example.org/red%09ros%C3%A9#red')
  362. // IPv4address
  363. t.equal(URI.normalize('//192.068.001.000'), '//192.68.1.0')
  364. // IPv6address, example from RFC 3513
  365. t.equal(URI.normalize('http://[1080::8:800:200C:417A]/'), 'http://[1080::8:800:200c:417a]/')
  366. // IPv6address, examples from RFC 5952
  367. t.equal(URI.normalize('//[2001:0db8::0001]/'), '//[2001:db8::1]/')
  368. t.equal(URI.normalize('//[2001:db8::1:0000:1]/'), '//[2001:db8::1:0:1]/')
  369. t.equal(URI.normalize('//[2001:db8:0:0:0:0:2:1]/'), '//[2001:db8::2:1]/')
  370. t.equal(URI.normalize('//[2001:db8:0:1:1:1:1:1]/'), '//[2001:db8:0:1:1:1:1:1]/')
  371. t.equal(URI.normalize('//[2001:0:0:1:0:0:0:1]/'), '//[2001:0:0:1::1]/')
  372. t.equal(URI.normalize('//[2001:db8:0:0:1:0:0:1]/'), '//[2001:db8::1:0:0:1]/')
  373. t.equal(URI.normalize('//[2001:DB8::1]/'), '//[2001:db8::1]/')
  374. t.equal(URI.normalize('//[0:0:0:0:0:ffff:192.0.2.1]/'), '//[::ffff:192.0.2.1]/')
  375. // Mixed IPv4 and IPv6 address
  376. t.equal(URI.normalize('//[1:2:3:4:5:6:192.0.2.1]/'), '//[1:2:3:4:5:6:192.0.2.1]/')
  377. t.equal(URI.normalize('//[1:2:3:4:5:6:192.068.001.000]/'), '//[1:2:3:4:5:6:192.68.1.0]/')
  378. t.end()
  379. })
  380. test('URI Equals', (t) => {
  381. // test from RFC 3986
  382. t.equal(URI.equal('example://a/b/c/%7Bfoo%7D', 'eXAMPLE://a/./b/../b/%63/%7bfoo%7d'), true)
  383. // test from RFC 3987
  384. t.equal(URI.equal('http://example.org/~user', 'http://example.org/%7euser'), true)
  385. t.end()
  386. })
  387. test('Escape Component', { skip: true }, (t) => {
  388. let chr
  389. for (let d = 0; d <= 129; ++d) {
  390. chr = String.fromCharCode(d)
  391. if (!chr.match(/[$&+,;=]/)) {
  392. t.equal(URI.escapeComponent(chr), encodeURIComponent(chr))
  393. } else {
  394. t.equal(URI.escapeComponent(chr), chr)
  395. }
  396. }
  397. t.equal(URI.escapeComponent('\u00c0'), encodeURIComponent('\u00c0'))
  398. t.equal(URI.escapeComponent('\u07ff'), encodeURIComponent('\u07ff'))
  399. t.equal(URI.escapeComponent('\u0800'), encodeURIComponent('\u0800'))
  400. t.equal(URI.escapeComponent('\u30a2'), encodeURIComponent('\u30a2'))
  401. t.end()
  402. })
  403. test('Unescape Component', { skip: true }, (t) => {
  404. let chr
  405. for (let d = 0; d <= 129; ++d) {
  406. chr = String.fromCharCode(d)
  407. t.equal(URI.unescapeComponent(encodeURIComponent(chr)), chr)
  408. }
  409. t.equal(URI.unescapeComponent(encodeURIComponent('\u00c0')), '\u00c0')
  410. t.equal(URI.unescapeComponent(encodeURIComponent('\u07ff')), '\u07ff')
  411. t.equal(URI.unescapeComponent(encodeURIComponent('\u0800')), '\u0800')
  412. t.equal(URI.unescapeComponent(encodeURIComponent('\u30a2')), '\u30a2')
  413. t.end()
  414. })
  415. const IRI_OPTION = { iri: true, unicodeSupport: true }
  416. test('IRI Parsing', { skip: true }, (t) => {
  417. const components = URI.parse('uri://us\xA0er:pa\uD7FFss@example.com:123/o\uF900ne/t\uFDCFwo.t\uFDF0hree?q1=a1\uF8FF\uE000&q2=a2#bo\uFFEFdy', IRI_OPTION)
  418. t.equal(components.error, undefined, 'all errors')
  419. t.equal(components.scheme, 'uri', 'scheme')
  420. t.equal(components.userinfo, 'us\xA0er:pa\uD7FFss', 'userinfo')
  421. t.equal(components.host, 'example.com', 'host')
  422. t.equal(components.port, 123, 'port')
  423. t.equal(components.path, '/o\uF900ne/t\uFDCFwo.t\uFDF0hree', 'path')
  424. t.equal(components.query, 'q1=a1\uF8FF\uE000&q2=a2', 'query')
  425. t.equal(components.fragment, 'bo\uFFEFdy', 'fragment')
  426. t.end()
  427. })
  428. test('IRI Serialization', { skip: true }, (t) => {
  429. const components = {
  430. scheme: 'uri',
  431. userinfo: 'us\xA0er:pa\uD7FFss',
  432. host: 'example.com',
  433. port: 123,
  434. path: '/o\uF900ne/t\uFDCFwo.t\uFDF0hree',
  435. query: 'q1=a1\uF8FF\uE000&q2=a2',
  436. fragment: 'bo\uFFEFdy\uE001'
  437. }
  438. t.equal(URI.serialize(components, IRI_OPTION), 'uri://us\xA0er:pa\uD7FFss@example.com:123/o\uF900ne/t\uFDCFwo.t\uFDF0hree?q1=a1\uF8FF\uE000&q2=a2#bo\uFFEFdy%EE%80%81')
  439. t.end()
  440. })
  441. test('IRI Normalizing', { skip: true }, (t) => {
  442. t.equal(URI.normalize('uri://www.example.org/red%09ros\xE9#red', IRI_OPTION), 'uri://www.example.org/red%09ros\xE9#red')
  443. t.end()
  444. })
  445. test('IRI Equals', { skip: true }, (t) => {
  446. // example from RFC 3987
  447. t.equal(URI.equal('example://a/b/c/%7Bfoo%7D/ros\xE9', 'eXAMPLE://a/./b/../b/%63/%7bfoo%7d/ros%C3%A9', IRI_OPTION), true)
  448. t.end()
  449. })
  450. test('Convert IRI to URI', { skip: true }, (t) => {
  451. // example from RFC 3987
  452. t.equal(URI.serialize(URI.parse('uri://www.example.org/red%09ros\xE9#red', IRI_OPTION)), 'uri://www.example.org/red%09ros%C3%A9#red')
  453. // Internationalized Domain Name conversion via punycode example from RFC 3987
  454. t.equal(URI.serialize(URI.parse('uri://r\xE9sum\xE9.example.org', { iri: true, domainHost: true }), { domainHost: true }), 'uri://xn--rsum-bpad.example.org')
  455. t.end()
  456. })
  457. test('Convert URI to IRI', { skip: true }, (t) => {
  458. // examples from RFC 3987
  459. t.equal(URI.serialize(URI.parse('uri://www.example.org/D%C3%BCrst'), IRI_OPTION), 'uri://www.example.org/D\xFCrst')
  460. t.equal(URI.serialize(URI.parse('uri://www.example.org/D%FCrst'), IRI_OPTION), 'uri://www.example.org/D%FCrst')
  461. t.equal(URI.serialize(URI.parse('uri://xn--99zt52a.example.org/%e2%80%ae'), IRI_OPTION), 'uri://xn--99zt52a.example.org/%E2%80%AE') // or uri://\u7D0D\u8C46.example.org/%E2%80%AE
  462. // Internationalized Domain Name conversion via punycode example from RFC 3987
  463. t.equal(URI.serialize(URI.parse('uri://xn--rsum-bpad.example.org', { domainHost: true }), { iri: true, domainHost: true }), 'uri://r\xE9sum\xE9.example.org')
  464. t.end()
  465. })
  466. if (URI.SCHEMES.http) {
  467. test('HTTP Equals', (t) => {
  468. // test from RFC 2616
  469. t.equal(URI.equal('http://abc.com:80/~smith/home.html', 'http://abc.com/~smith/home.html'), true)
  470. t.equal(URI.equal('http://ABC.com/%7Esmith/home.html', 'http://abc.com/~smith/home.html'), true)
  471. t.equal(URI.equal('http://ABC.com:/%7esmith/home.html', 'http://abc.com/~smith/home.html'), true)
  472. t.equal(URI.equal('HTTP://ABC.COM', 'http://abc.com/'), true)
  473. // test from RFC 3986
  474. t.equal(URI.equal('http://example.com:/', 'http://example.com:80/'), true)
  475. t.end()
  476. })
  477. }
  478. if (URI.SCHEMES.https) {
  479. test('HTTPS Equals', (t) => {
  480. t.equal(URI.equal('https://example.com', 'https://example.com:443/'), true)
  481. t.equal(URI.equal('https://example.com:/', 'https://example.com:443/'), true)
  482. t.end()
  483. })
  484. }
  485. if (URI.SCHEMES.urn) {
  486. test('URN Parsing', (t) => {
  487. // example from RFC 2141
  488. const components = URI.parse('urn:foo:a123,456')
  489. t.equal(components.error, undefined, 'errors')
  490. t.equal(components.scheme, 'urn', 'scheme')
  491. t.equal(components.userinfo, undefined, 'userinfo')
  492. t.equal(components.host, undefined, 'host')
  493. t.equal(components.port, undefined, 'port')
  494. t.equal(components.path, undefined, 'path')
  495. t.equal(components.query, undefined, 'query')
  496. t.equal(components.fragment, undefined, 'fragment')
  497. t.equal(components.nid, 'foo', 'nid')
  498. t.equal(components.nss, 'a123,456', 'nss')
  499. t.end()
  500. })
  501. test('URN Serialization', (t) => {
  502. // example from RFC 2141
  503. const components = {
  504. scheme: 'urn',
  505. nid: 'foo',
  506. nss: 'a123,456'
  507. }
  508. t.equal(URI.serialize(components), 'urn:foo:a123,456')
  509. t.end()
  510. })
  511. test('URN Equals', { skip: true }, (t) => {
  512. // test from RFC 2141
  513. t.equal(URI.equal('urn:foo:a123,456', 'urn:foo:a123,456'), true)
  514. t.equal(URI.equal('urn:foo:a123,456', 'URN:foo:a123,456'), true)
  515. t.equal(URI.equal('urn:foo:a123,456', 'urn:FOO:a123,456'), true)
  516. t.equal(URI.equal('urn:foo:a123,456', 'urn:foo:A123,456'), false)
  517. t.equal(URI.equal('urn:foo:a123%2C456', 'URN:FOO:a123%2c456'), true)
  518. t.end()
  519. })
  520. test('URN Resolving', (t) => {
  521. // example from epoberezkin
  522. t.equal(URI.resolve('', 'urn:some:ip:prop'), 'urn:some:ip:prop')
  523. t.equal(URI.resolve('#', 'urn:some:ip:prop'), 'urn:some:ip:prop')
  524. t.equal(URI.resolve('urn:some:ip:prop', 'urn:some:ip:prop'), 'urn:some:ip:prop')
  525. t.equal(URI.resolve('urn:some:other:prop', 'urn:some:ip:prop'), 'urn:some:ip:prop')
  526. t.end()
  527. })
  528. test('UUID Parsing', (t) => {
  529. // example from RFC 4122
  530. let components = URI.parse('urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6')
  531. t.equal(components.error, undefined, 'errors')
  532. t.equal(components.scheme, 'urn', 'scheme')
  533. t.equal(components.userinfo, undefined, 'userinfo')
  534. t.equal(components.host, undefined, 'host')
  535. t.equal(components.port, undefined, 'port')
  536. t.equal(components.path, undefined, 'path')
  537. t.equal(components.query, undefined, 'query')
  538. t.equal(components.fragment, undefined, 'fragment')
  539. t.equal(components.nid, 'uuid', 'nid')
  540. t.equal(components.nss, undefined, 'nss')
  541. t.equal(components.uuid, 'f81d4fae-7dec-11d0-a765-00a0c91e6bf6', 'uuid')
  542. components = URI.parse('urn:uuid:notauuid-7dec-11d0-a765-00a0c91e6bf6')
  543. t.notEqual(components.error, undefined, 'errors')
  544. t.end()
  545. })
  546. test('UUID Serialization', (t) => {
  547. // example from RFC 4122
  548. let components = {
  549. scheme: 'urn',
  550. nid: 'uuid',
  551. uuid: 'f81d4fae-7dec-11d0-a765-00a0c91e6bf6'
  552. }
  553. t.equal(URI.serialize(components), 'urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6')
  554. components = {
  555. scheme: 'urn',
  556. nid: 'uuid',
  557. uuid: 'notauuid-7dec-11d0-a765-00a0c91e6bf6'
  558. }
  559. t.equal(URI.serialize(components), 'urn:uuid:notauuid-7dec-11d0-a765-00a0c91e6bf6')
  560. t.end()
  561. })
  562. test('UUID Equals', (t) => {
  563. t.equal(URI.equal('URN:UUID:F81D4FAE-7DEC-11D0-A765-00A0C91E6BF6', 'urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6'), true)
  564. t.end()
  565. })
  566. test('URN NID Override', (t) => {
  567. let components = URI.parse('urn:foo:f81d4fae-7dec-11d0-a765-00a0c91e6bf6', { nid: 'uuid' })
  568. t.equal(components.error, undefined, 'errors')
  569. t.equal(components.scheme, 'urn', 'scheme')
  570. t.equal(components.path, undefined, 'path')
  571. t.equal(components.nid, 'foo', 'nid')
  572. t.equal(components.nss, undefined, 'nss')
  573. t.equal(components.uuid, 'f81d4fae-7dec-11d0-a765-00a0c91e6bf6', 'uuid')
  574. components = {
  575. scheme: 'urn',
  576. nid: 'foo',
  577. uuid: 'f81d4fae-7dec-11d0-a765-00a0c91e6bf6'
  578. }
  579. t.equal(URI.serialize(components, { nid: 'uuid' }), 'urn:foo:f81d4fae-7dec-11d0-a765-00a0c91e6bf6')
  580. t.end()
  581. })
  582. }
  583. if (URI.SCHEMES.mailto) {
  584. test('Mailto Parse', (t) => {
  585. let components
  586. // tests from RFC 6068
  587. components = URI.parse('mailto:chris@example.com')
  588. t.equal(components.error, undefined, 'error')
  589. t.equal(components.scheme, 'mailto', 'scheme')
  590. t.equal(components.userinfo, undefined, 'userinfo')
  591. t.equal(components.host, undefined, 'host')
  592. t.equal(components.port, undefined, 'port')
  593. t.equal(components.path, undefined, 'path')
  594. t.equal(components.query, undefined, 'query')
  595. t.equal(components.fragment, undefined, 'fragment')
  596. t.deepEqual(components.to, ['chris@example.com'], 'to')
  597. t.equal(components.subject, undefined, 'subject')
  598. t.equal(components.body, undefined, 'body')
  599. t.equal(components.headers, undefined, 'headers')
  600. components = URI.parse('mailto:infobot@example.com?subject=current-issue')
  601. t.deepEqual(components.to, ['infobot@example.com'], 'to')
  602. t.equal(components.subject, 'current-issue', 'subject')
  603. components = URI.parse('mailto:infobot@example.com?body=send%20current-issue')
  604. t.deepEqual(components.to, ['infobot@example.com'], 'to')
  605. t.equal(components.body, 'send current-issue', 'body')
  606. components = URI.parse('mailto:infobot@example.com?body=send%20current-issue%0D%0Asend%20index')
  607. t.deepEqual(components.to, ['infobot@example.com'], 'to')
  608. t.equal(components.body, 'send current-issue\x0D\x0Asend index', 'body')
  609. components = URI.parse('mailto:list@example.org?In-Reply-To=%3C3469A91.D10AF4C@example.com%3E')
  610. t.deepEqual(components.to, ['list@example.org'], 'to')
  611. t.deepEqual(components.headers, { 'In-Reply-To': '<3469A91.D10AF4C@example.com>' }, 'headers')
  612. components = URI.parse('mailto:majordomo@example.com?body=subscribe%20bamboo-l')
  613. t.deepEqual(components.to, ['majordomo@example.com'], 'to')
  614. t.equal(components.body, 'subscribe bamboo-l', 'body')
  615. components = URI.parse('mailto:joe@example.com?cc=bob@example.com&body=hello')
  616. t.deepEqual(components.to, ['joe@example.com'], 'to')
  617. t.equal(components.body, 'hello', 'body')
  618. t.deepEqual(components.headers, { cc: 'bob@example.com' }, 'headers')
  619. components = URI.parse('mailto:joe@example.com?cc=bob@example.com?body=hello')
  620. if (URI.VALIDATE_SUPPORT) t.ok(components.error, 'invalid header fields')
  621. components = URI.parse('mailto:gorby%25kremvax@example.com')
  622. t.deepEqual(components.to, ['gorby%kremvax@example.com'], 'to gorby%kremvax@example.com')
  623. components = URI.parse('mailto:unlikely%3Faddress@example.com?blat=foop')
  624. t.deepEqual(components.to, ['unlikely?address@example.com'], 'to unlikely?address@example.com')
  625. t.deepEqual(components.headers, { blat: 'foop' }, 'headers')
  626. components = URI.parse('mailto:Mike%26family@example.org')
  627. t.deepEqual(components.to, ['Mike&family@example.org'], 'to Mike&family@example.org')
  628. components = URI.parse('mailto:%22not%40me%22@example.org')
  629. t.deepEqual(components.to, ['"not@me"@example.org'], 'to ' + '"not@me"@example.org')
  630. components = URI.parse('mailto:%22oh%5C%5Cno%22@example.org')
  631. t.deepEqual(components.to, ['"oh\\\\no"@example.org'], 'to ' + '"oh\\\\no"@example.org')
  632. components = URI.parse("mailto:%22%5C%5C%5C%22it's%5C%20ugly%5C%5C%5C%22%22@example.org")
  633. t.deepEqual(components.to, ['"\\\\\\"it\'s\\ ugly\\\\\\""@example.org'], 'to ' + '"\\\\\\"it\'s\\ ugly\\\\\\""@example.org')
  634. components = URI.parse('mailto:user@example.org?subject=caf%C3%A9')
  635. t.deepEqual(components.to, ['user@example.org'], 'to')
  636. t.equal(components.subject, 'caf\xE9', 'subject')
  637. components = URI.parse('mailto:user@example.org?subject=%3D%3Futf-8%3FQ%3Fcaf%3DC3%3DA9%3F%3D')
  638. t.deepEqual(components.to, ['user@example.org'], 'to')
  639. t.equal(components.subject, '=?utf-8?Q?caf=C3=A9?=', 'subject') // TODO: Verify this
  640. components = URI.parse('mailto:user@example.org?subject=%3D%3Fiso-8859-1%3FQ%3Fcaf%3DE9%3F%3D')
  641. t.deepEqual(components.to, ['user@example.org'], 'to')
  642. t.equal(components.subject, '=?iso-8859-1?Q?caf=E9?=', 'subject') // TODO: Verify this
  643. components = URI.parse('mailto:user@example.org?subject=caf%C3%A9&body=caf%C3%A9')
  644. t.deepEqual(components.to, ['user@example.org'], 'to')
  645. t.equal(components.subject, 'caf\xE9', 'subject')
  646. t.equal(components.body, 'caf\xE9', 'body')
  647. if (URI.IRI_SUPPORT) {
  648. components = URI.parse('mailto:user@%E7%B4%8D%E8%B1%86.example.org?subject=Test&body=NATTO')
  649. t.deepEqual(components.to, ['user@xn--99zt52a.example.org'], 'to')
  650. t.equal(components.subject, 'Test', 'subject')
  651. t.equal(components.body, 'NATTO', 'body')
  652. }
  653. t.end()
  654. })
  655. test('Mailto Serialize', (t) => {
  656. // tests from RFC 6068
  657. t.equal(URI.serialize({ scheme: 'mailto', to: ['chris@example.com'] }), 'mailto:chris@example.com')
  658. t.equal(URI.serialize({ scheme: 'mailto', to: ['infobot@example.com'], body: 'current-issue' }), 'mailto:infobot@example.com?body=current-issue')
  659. t.equal(URI.serialize({ scheme: 'mailto', to: ['infobot@example.com'], body: 'send current-issue' }), 'mailto:infobot@example.com?body=send%20current-issue')
  660. t.equal(URI.serialize({ scheme: 'mailto', to: ['infobot@example.com'], body: 'send current-issue\x0D\x0Asend index' }), 'mailto:infobot@example.com?body=send%20current-issue%0D%0Asend%20index')
  661. t.equal(URI.serialize({ scheme: 'mailto', to: ['list@example.org'], headers: { 'In-Reply-To': '<3469A91.D10AF4C@example.com>' } }), 'mailto:list@example.org?In-Reply-To=%3C3469A91.D10AF4C@example.com%3E')
  662. t.equal(URI.serialize({ scheme: 'mailto', to: ['majordomo@example.com'], body: 'subscribe bamboo-l' }), 'mailto:majordomo@example.com?body=subscribe%20bamboo-l')
  663. t.equal(URI.serialize({ scheme: 'mailto', to: ['joe@example.com'], headers: { cc: 'bob@example.com', body: 'hello' } }), 'mailto:joe@example.com?cc=bob@example.com&body=hello')
  664. t.equal(URI.serialize({ scheme: 'mailto', to: ['gorby%25kremvax@example.com'] }), 'mailto:gorby%25kremvax@example.com')
  665. t.equal(URI.serialize({ scheme: 'mailto', to: ['unlikely%3Faddress@example.com'], headers: { blat: 'foop' } }), 'mailto:unlikely%3Faddress@example.com?blat=foop')
  666. t.equal(URI.serialize({ scheme: 'mailto', to: ['Mike&family@example.org'] }), 'mailto:Mike%26family@example.org')
  667. t.equal(URI.serialize({ scheme: 'mailto', to: ['"not@me"@example.org'] }), 'mailto:%22not%40me%22@example.org')
  668. t.equal(URI.serialize({ scheme: 'mailto', to: ['"oh\\\\no"@example.org'] }), 'mailto:%22oh%5C%5Cno%22@example.org')
  669. t.equal(URI.serialize({ scheme: 'mailto', to: ['"\\\\\\"it\'s\\ ugly\\\\\\""@example.org'] }), "mailto:%22%5C%5C%5C%22it's%5C%20ugly%5C%5C%5C%22%22@example.org")
  670. t.equal(URI.serialize({ scheme: 'mailto', to: ['user@example.org'], subject: 'caf\xE9' }), 'mailto:user@example.org?subject=caf%C3%A9')
  671. t.equal(URI.serialize({ scheme: 'mailto', to: ['user@example.org'], subject: '=?utf-8?Q?caf=C3=A9?=' }), 'mailto:user@example.org?subject=%3D%3Futf-8%3FQ%3Fcaf%3DC3%3DA9%3F%3D')
  672. t.equal(URI.serialize({ scheme: 'mailto', to: ['user@example.org'], subject: '=?iso-8859-1?Q?caf=E9?=' }), 'mailto:user@example.org?subject=%3D%3Fiso-8859-1%3FQ%3Fcaf%3DE9%3F%3D')
  673. t.equal(URI.serialize({ scheme: 'mailto', to: ['user@example.org'], subject: 'caf\xE9', body: 'caf\xE9' }), 'mailto:user@example.org?subject=caf%C3%A9&body=caf%C3%A9')
  674. if (URI.IRI_SUPPORT) {
  675. t.equal(URI.serialize({ scheme: 'mailto', to: ['us\xE9r@\u7d0d\u8c46.example.org'], subject: 'Test', body: 'NATTO' }), 'mailto:us%C3%A9r@xn--99zt52a.example.org?subject=Test&body=NATTO')
  676. }
  677. t.end()
  678. })
  679. test('Mailto Equals', (t) => {
  680. // tests from RFC 6068
  681. t.equal(URI.equal('mailto:addr1@an.example,addr2@an.example', 'mailto:?to=addr1@an.example,addr2@an.example'), true)
  682. t.equal(URI.equal('mailto:?to=addr1@an.example,addr2@an.example', 'mailto:addr1@an.example?to=addr2@an.example'), true)
  683. t.end()
  684. })
  685. }
  686. if (URI.SCHEMES.ws) {
  687. test('WS Parse', (t) => {
  688. let components
  689. // example from RFC 6455, Sec 4.1
  690. components = URI.parse('ws://example.com/chat')
  691. t.equal(components.error, undefined, 'error')
  692. t.equal(components.scheme, 'ws', 'scheme')
  693. t.equal(components.userinfo, undefined, 'userinfo')
  694. t.equal(components.host, 'example.com', 'host')
  695. t.equal(components.port, undefined, 'port')
  696. t.equal(components.path, undefined, 'path')
  697. t.equal(components.query, undefined, 'query')
  698. t.equal(components.fragment, undefined, 'fragment')
  699. t.equal(components.resourceName, '/chat', 'resourceName')
  700. t.equal(components.secure, false, 'secure')
  701. components = URI.parse('ws://example.com/foo?bar=baz')
  702. t.equal(components.error, undefined, 'error')
  703. t.equal(components.scheme, 'ws', 'scheme')
  704. t.equal(components.userinfo, undefined, 'userinfo')
  705. t.equal(components.host, 'example.com', 'host')
  706. t.equal(components.port, undefined, 'port')
  707. t.equal(components.path, undefined, 'path')
  708. t.equal(components.query, undefined, 'query')
  709. t.equal(components.fragment, undefined, 'fragment')
  710. t.equal(components.resourceName, '/foo?bar=baz', 'resourceName')
  711. t.equal(components.secure, false, 'secure')
  712. components = URI.parse('ws://example.com/?bar=baz')
  713. t.equal(components.resourceName, '/?bar=baz', 'resourceName')
  714. t.end()
  715. })
  716. test('WS Serialize', (t) => {
  717. t.equal(URI.serialize({ scheme: 'ws' }), 'ws:')
  718. t.equal(URI.serialize({ scheme: 'ws', host: 'example.com' }), 'ws://example.com')
  719. t.equal(URI.serialize({ scheme: 'ws', resourceName: '/' }), 'ws:')
  720. t.equal(URI.serialize({ scheme: 'ws', resourceName: '/foo' }), 'ws:/foo')
  721. t.equal(URI.serialize({ scheme: 'ws', resourceName: '/foo?bar' }), 'ws:/foo?bar')
  722. t.equal(URI.serialize({ scheme: 'ws', secure: false }), 'ws:')
  723. t.equal(URI.serialize({ scheme: 'ws', secure: true }), 'wss:')
  724. t.equal(URI.serialize({ scheme: 'ws', host: 'example.com', resourceName: '/foo' }), 'ws://example.com/foo')
  725. t.equal(URI.serialize({ scheme: 'ws', host: 'example.com', resourceName: '/foo?bar' }), 'ws://example.com/foo?bar')
  726. t.equal(URI.serialize({ scheme: 'ws', host: 'example.com', secure: false }), 'ws://example.com')
  727. t.equal(URI.serialize({ scheme: 'ws', host: 'example.com', secure: true }), 'wss://example.com')
  728. t.equal(URI.serialize({ scheme: 'ws', host: 'example.com', resourceName: '/foo?bar', secure: false }), 'ws://example.com/foo?bar')
  729. t.equal(URI.serialize({ scheme: 'ws', host: 'example.com', resourceName: '/foo?bar', secure: true }), 'wss://example.com/foo?bar')
  730. t.end()
  731. })
  732. test('WS Equal', (t) => {
  733. t.equal(URI.equal('WS://ABC.COM:80/chat#one', 'ws://abc.com/chat'), true)
  734. t.end()
  735. })
  736. test('WS Normalize', (t) => {
  737. t.equal(URI.normalize('ws://example.com:80/foo#hash'), 'ws://example.com/foo')
  738. t.end()
  739. })
  740. }
  741. if (URI.SCHEMES.wss) {
  742. test('WSS Parse', (t) => {
  743. let components
  744. // example from RFC 6455, Sec 4.1
  745. components = URI.parse('wss://example.com/chat')
  746. t.equal(components.error, undefined, 'error')
  747. t.equal(components.scheme, 'wss', 'scheme')
  748. t.equal(components.userinfo, undefined, 'userinfo')
  749. t.equal(components.host, 'example.com', 'host')
  750. t.equal(components.port, undefined, 'port')
  751. t.equal(components.path, undefined, 'path')
  752. t.equal(components.query, undefined, 'query')
  753. t.equal(components.fragment, undefined, 'fragment')
  754. t.equal(components.resourceName, '/chat', 'resourceName')
  755. t.equal(components.secure, true, 'secure')
  756. components = URI.parse('wss://example.com/foo?bar=baz')
  757. t.equal(components.error, undefined, 'error')
  758. t.equal(components.scheme, 'wss', 'scheme')
  759. t.equal(components.userinfo, undefined, 'userinfo')
  760. t.equal(components.host, 'example.com', 'host')
  761. t.equal(components.port, undefined, 'port')
  762. t.equal(components.path, undefined, 'path')
  763. t.equal(components.query, undefined, 'query')
  764. t.equal(components.fragment, undefined, 'fragment')
  765. t.equal(components.resourceName, '/foo?bar=baz', 'resourceName')
  766. t.equal(components.secure, true, 'secure')
  767. components = URI.parse('wss://example.com/?bar=baz')
  768. t.equal(components.resourceName, '/?bar=baz', 'resourceName')
  769. t.end()
  770. })
  771. test('WSS Serialize', (t) => {
  772. t.equal(URI.serialize({ scheme: 'wss' }), 'wss:')
  773. t.equal(URI.serialize({ scheme: 'wss', host: 'example.com' }), 'wss://example.com')
  774. t.equal(URI.serialize({ scheme: 'wss', resourceName: '/' }), 'wss:')
  775. t.equal(URI.serialize({ scheme: 'wss', resourceName: '/foo' }), 'wss:/foo')
  776. t.equal(URI.serialize({ scheme: 'wss', resourceName: '/foo?bar' }), 'wss:/foo?bar')
  777. t.equal(URI.serialize({ scheme: 'wss', secure: false }), 'ws:')
  778. t.equal(URI.serialize({ scheme: 'wss', secure: true }), 'wss:')
  779. t.equal(URI.serialize({ scheme: 'wss', host: 'example.com', resourceName: '/foo' }), 'wss://example.com/foo')
  780. t.equal(URI.serialize({ scheme: 'wss', host: 'example.com', resourceName: '/foo?bar' }), 'wss://example.com/foo?bar')
  781. t.equal(URI.serialize({ scheme: 'wss', host: 'example.com', secure: false }), 'ws://example.com')
  782. t.equal(URI.serialize({ scheme: 'wss', host: 'example.com', secure: true }), 'wss://example.com')
  783. t.equal(URI.serialize({ scheme: 'wss', host: 'example.com', resourceName: '/foo?bar', secure: false }), 'ws://example.com/foo?bar')
  784. t.equal(URI.serialize({ scheme: 'wss', host: 'example.com', resourceName: '/foo?bar', secure: true }), 'wss://example.com/foo?bar')
  785. t.end()
  786. })
  787. test('WSS Equal', (t) => {
  788. t.equal(URI.equal('WSS://ABC.COM:443/chat#one', 'wss://abc.com/chat'), true)
  789. t.end()
  790. })
  791. test('WSS Normalize', (t) => {
  792. t.equal(URI.normalize('wss://example.com:443/foo#hash'), 'wss://example.com/foo')
  793. t.end()
  794. })
  795. }