equal.test.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. 'use strict'
  2. const test = require('tape')
  3. const fastURI = require('..')
  4. const fn = fastURI.equal
  5. const runTest = (t, suite) => {
  6. suite.forEach(s => {
  7. const operator = s.result ? '==' : '!='
  8. t.equal(fn(s.pair[0], s.pair[1]), s.result, `${s.pair[0]} ${operator} ${s.pair[1]}`)
  9. t.equal(fn(s.pair[1], s.pair[0]), s.result, `${s.pair[1]} ${operator} ${s.pair[0]}`)
  10. })
  11. }
  12. test('URI Equals', (t) => {
  13. const suite = [
  14. { pair: ['example://a/b/c/%7Bfoo%7D', 'eXAMPLE://a/./b/../b/%63/%7bfoo%7d'], result: true }, // test from RFC 3986
  15. { pair: ['http://example.org/~user', 'http://example.org/%7euser'], result: true } // test from RFC 3987
  16. ]
  17. runTest(t, suite)
  18. t.end()
  19. })
  20. test('URI Equals rejects malformed object input even when identical', (t) => {
  21. const malformed = { scheme: 'http', host: 'example.com', port: 99999, path: '/x' }
  22. t.equal(fn(malformed, malformed), false)
  23. t.end()
  24. })
  25. test('URI Equals preserves case-sensitive components', (t) => {
  26. const suite = [
  27. { pair: ['http://example.com/Admin', 'http://example.com/admin'], result: false },
  28. { pair: ['http://example.com/?token=SECRET', 'http://example.com/?token=secret'], result: false },
  29. { pair: ['http://example.com/#Section', 'http://example.com/#section'], result: false },
  30. { pair: ['http://User@example.com/', 'http://user@example.com/'], result: false },
  31. { pair: ['urn:foo:CaseSensitive', 'urn:foo:casesensitive'], result: false },
  32. { pair: ['ws://example.com/Chat', 'ws://example.com/chat'], result: false },
  33. { pair: ['ws://example.com/?token=SECRET', 'ws://example.com/?token=secret'], result: false },
  34. { pair: [{ scheme: 'http', host: 'example.com', path: '/Admin' }, { scheme: 'http', host: 'example.com', path: '/admin' }], result: false }
  35. ]
  36. runTest(t, suite)
  37. t.end()
  38. })
  39. test('URI Equals folds normalized scheme and host case', (t) => {
  40. const suite = [
  41. { pair: ['HTTP://EXAMPLE.COM/resource', 'http://example.com/resource'], result: true },
  42. { pair: [{ scheme: 'HTTP', host: 'EXAMPLE.COM', path: '/resource' }, { scheme: 'http', host: 'example.com', path: '/resource' }], result: true }
  43. ]
  44. runTest(t, suite)
  45. t.end()
  46. })
  47. // test('IRI Equals', (t) => {
  48. // // example from RFC 3987
  49. // 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)
  50. // t.end()
  51. // })
  52. test('HTTP Equals', (t) => {
  53. const suite = [
  54. // test from RFC 2616
  55. { pair: ['http://abc.com:80/~smith/home.html', 'http://abc.com/~smith/home.html'], result: true },
  56. { pair: [{ scheme: 'http', host: 'abc.com', port: 80, path: '/~smith/home.html' }, 'http://abc.com/~smith/home.html'], result: true },
  57. { pair: ['http://ABC.com/%7Esmith/home.html', 'http://abc.com/~smith/home.html'], result: true },
  58. { pair: ['http://ABC.com:/%7esmith/home.html', 'http://abc.com/~smith/home.html'], result: true },
  59. { pair: ['HTTP://ABC.COM', 'http://abc.com/'], result: true },
  60. // test from RFC 3986
  61. { pair: ['http://example.com:/', 'http://example.com:80/'], result: true }
  62. ]
  63. runTest(t, suite)
  64. t.end()
  65. })
  66. test('HTTPS Equals', (t) => {
  67. const suite = [
  68. { pair: ['https://example.com', 'https://example.com:443/'], result: true },
  69. { pair: ['https://example.com:/', 'https://example.com:443/'], result: true }
  70. ]
  71. runTest(t, suite)
  72. t.end()
  73. })
  74. test('URN Equals', (t) => {
  75. const suite = [
  76. // test from RFC 2141
  77. { pair: ['urn:foo:a123,456', 'urn:foo:a123,456'], result: true },
  78. { pair: ['urn:foo:a123,456', 'URN:foo:a123,456'], result: true },
  79. { pair: ['urn:foo:a123,456', 'urn:FOO:a123,456'], result: true }
  80. ]
  81. // Disabling for now as the whole equal logic might need
  82. // to be refactored
  83. // t.equal(URI.equal('urn:foo:a123,456', 'urn:foo:A123,456'), false)
  84. // t.equal(URI.equal('urn:foo:a123%2C456', 'URN:FOO:a123%2c456'), true)
  85. runTest(t, suite)
  86. t.equal(fn('urn:', 'urn:FOO:a123,456'), false, 'malformed URN fails equality safely')
  87. t.end()
  88. })
  89. test('UUID Equals', (t) => {
  90. const suite = [
  91. { pair: ['URN:UUID:F81D4FAE-7DEC-11D0-A765-00A0C91E6BF6', 'urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6'], result: true }
  92. ]
  93. runTest(t, suite)
  94. t.end()
  95. })
  96. // test('Mailto Equals', (t) => {
  97. // // tests from RFC 6068
  98. // t.equal(URI.equal('mailto:addr1@an.example,addr2@an.example', 'mailto:?to=addr1@an.example,addr2@an.example'), true)
  99. // t.equal(URI.equal('mailto:?to=addr1@an.example,addr2@an.example', 'mailto:addr1@an.example?to=addr2@an.example'), true)
  100. // t.end()
  101. // })
  102. test('WS Equal', (t) => {
  103. const suite = [
  104. { pair: ['WS://ABC.COM:80/chat#one', 'ws://abc.com/chat'], result: true }
  105. ]
  106. runTest(t, suite)
  107. t.end()
  108. })
  109. test('WSS Equal', (t) => {
  110. const suite = [
  111. { pair: ['WSS://ABC.COM:443/chat#one', 'wss://abc.com/chat'], result: true }
  112. ]
  113. runTest(t, suite)
  114. t.end()
  115. })
  116. test('URI Equals tolerates malformed fragments', (t) => {
  117. t.equal(
  118. fastURI.equal('http://example.com/#%E0%A4A', 'http://example.com/#%E0%A4A'),
  119. true,
  120. 'malformed fragment does not throw during equality checks'
  121. )
  122. t.end()
  123. })