Browse Source

test: more comprehensive IDNA test cases

- Split the tests out to a separate file
- Add invalid cases
- Add tests for url.domainTo*()
- Re-enable previously broken WPT URL parsing tests

PR-URL: https://github.com/nodejs/node/pull/11549
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
v6
Timothy Gu 8 years ago
parent
commit
6c213978b7
  1. 217
      test/fixtures/url-idna.js
  2. 62
      test/fixtures/url-tests.js
  3. 85
      test/parallel/test-icu-punycode.js
  4. 36
      test/parallel/test-whatwg-url-domainto.js

217
test/fixtures/url-idna.js

@ -0,0 +1,217 @@
'use strict';
// Credit for list: http://www.i18nguy.com/markup/idna-examples.html
module.exports = {
valid: [
{ ascii: 'xn--mgbaal8b0b9b2b.icom.museum',
unicode: 'افغانستا.icom.museum'
},
{
ascii: 'xn--lgbbat1ad8j.icom.museum',
unicode: 'الجزائر.icom.museum'
},
{
ascii: 'xn--sterreich-z7a.icom.museum',
unicode: 'österreich.icom.museum'
},
{
ascii: 'xn--54b6eqazv8bc7e.icom.museum',
unicode: 'বাংলাদেশ.icom.museum'
},
{
ascii: 'xn--80abmy0agn7e.icom.museum',
unicode: 'беларусь.icom.museum'
},
{
ascii: 'xn--belgi-rsa.icom.museum',
unicode: 'belgië.icom.museum'
},
{
ascii: 'xn--80abgvm6a7d2b.icom.museum',
unicode: 'българия.icom.museum'
},
{
ascii: 'xn--mgbfqim.icom.museum',
unicode: 'تشادر.icom.museum'
},
{
ascii: 'xn--fiqs8s.icom.museum',
unicode: '中国.icom.museum'
},
{
ascii: 'xn--mgbu4chg.icom.museum',
unicode: 'القمر.icom.museum'
},
{
ascii: 'xn--vxakcego.icom.museum',
unicode: 'κυπρος.icom.museum'
},
{
ascii: 'xn--eskrepublika-ebb62d.icom.museum',
unicode: 'českárepublika.icom.museum'
},
{
ascii: 'xn--wgbh1c.icom.museum',
unicode: 'مصر.icom.museum'
},
{
ascii: 'xn--hxakic4aa.icom.museum',
unicode: 'ελλάδα.icom.museum'
},
{
ascii: 'xn--magyarorszg-t7a.icom.museum',
unicode: 'magyarország.icom.museum'
},
{
ascii: 'xn--sland-ysa.icom.museum',
unicode: 'ísland.icom.museum'
},
{
ascii: 'xn--h2brj9c.icom.museum',
unicode: 'भारत.icom.museum'
},
{
ascii: 'xn--mgba3a4fra.icom.museum',
unicode: 'ايران.icom.museum'
},
{
ascii: 'xn--ire-9la.icom.museum',
unicode: 'éire.icom.museum'
},
{
ascii: 'xn--4dbklr2c8d.xn--4dbrk0ce.museum',
unicode: 'איקו״ם.ישראל.museum'
},
{
ascii: 'xn--wgv71a.icom.museum',
unicode: '日本.icom.museum'
},
{
ascii: 'xn--igbhzh7gpa.icom.museum',
unicode: 'الأردن.icom.museum'
},
{
ascii: 'xn--80aaa0a6awh12ed.icom.museum',
unicode: 'қазақстан.icom.museum'
},
{
ascii: 'xn--3e0b707e.icom.museum',
unicode: '한국.icom.museum'
},
{
ascii: 'xn--80afmksoji0fc.icom.museum',
unicode: 'кыргызстан.icom.museum'
},
{
ascii: 'xn--q7ce6a.icom.museum',
unicode: 'ລາວ.icom.museum'
},
{
ascii: 'xn--mgbb7fjb.icom.museum',
unicode: 'لبنان.icom.museum'
},
{
ascii: 'xn--80aaldqjmmi6x.icom.museum',
unicode: 'македонија.icom.museum'
},
{
ascii: 'xn--mgbah1a3hjkrd.icom.museum',
unicode: 'موريتانيا.icom.museum'
},
{
ascii: 'xn--mxico-bsa.icom.museum',
unicode: 'méxico.icom.museum'
},
{
ascii: 'xn--c1aqabffc0aq.icom.museum',
unicode: 'монголулс.icom.museum'
},
{
ascii: 'xn--mgbc0a9azcg.icom.museum',
unicode: 'المغرب.icom.museum'
},
{
ascii: 'xn--l2bey1c2b.icom.museum',
unicode: 'नेपाल.icom.museum'
},
{
ascii: 'xn--mgb9awbf.icom.museum',
unicode: 'عمان.icom.museum'
},
{
ascii: 'xn--wgbl6a.icom.museum',
unicode: 'قطر.icom.museum'
},
{
ascii: 'xn--romnia-yta.icom.museum',
unicode: 'românia.icom.museum'
},
{
ascii: 'xn--h1alffa9f.xn--h1aegh.museum',
unicode: 'россия.иком.museum'
},
{
ascii: 'xn--80aaabm1ab4blmeec9e7n.xn--h1aegh.museum',
unicode: 'србијаицрнагора.иком.museum'
},
{
ascii: 'xn--xkc2al3hye2a.icom.museum',
unicode: 'இலங்கை.icom.museum'
},
{
ascii: 'xn--espaa-rta.icom.museum',
unicode: 'españa.icom.museum'
},
{
ascii: 'xn--o3cw4h.icom.museum',
unicode: 'ไทย.icom.museum'
},
{
ascii: 'xn--pgbs0dh.icom.museum',
unicode: 'تونس.icom.museum'
},
{
ascii: 'xn--trkiye-3ya.icom.museum',
unicode: 'türkiye.icom.museum'
},
{
ascii: 'xn--80aaxgrpt.icom.museum',
unicode: 'украина.icom.museum'
},
{
ascii: 'xn--vitnam-jk8b.icom.museum',
unicode: 'việtnam.icom.museum'
},
// long URL
{
ascii: `${`${'a'.repeat(63)}.`.repeat(3)}com`,
unicode: `${`${'a'.repeat(63)}.`.repeat(3)}com`
}
],
invalid: [
// long label
{
url: `${'a'.repeat(64)}.com`,
mode: 'ascii'
},
// long URL
{
url: `${`${'a'.repeat(63)}.`.repeat(4)}com`,
mode: 'ascii'
},
// invalid character
{
url: '\ufffd.com',
mode: 'ascii'
},
{
url: '\ufffd.com',
mode: 'unicode'
},
// invalid Punycode
{
url: 'xn---abc.com',
mode: 'unicode'
}
]
}

62
test/fixtures/url-tests.js

@ -3589,17 +3589,17 @@ module.exports =
"base": "http://other.com/", "base": "http://other.com/",
"failure": true "failure": true
}, },
// "U+FFFD", "U+FFFD",
// { {
// "input": "https://\ufffd", "input": "https://\ufffd",
// "base": "about:blank", "base": "about:blank",
// "failure": true "failure": true
// }, },
// { {
// "input": "https://%EF%BF%BD", "input": "https://%EF%BF%BD",
// "base": "about:blank", "base": "about:blank",
// "failure": true "failure": true
// }, },
{ {
"input": "https://x/\ufffd?\ufffd#\ufffd", "input": "https://x/\ufffd?\ufffd#\ufffd",
"base": "about:blank", "base": "about:blank",
@ -4497,26 +4497,26 @@ module.exports =
"hash": "" "hash": ""
}, },
"# Hosts and percent-encoding", "# Hosts and percent-encoding",
// { {
// "input": "ftp://example.com%80/", "input": "ftp://example.com%80/",
// "base": "about:blank", "base": "about:blank",
// "failure": true "failure": true
// }, },
// { {
// "input": "ftp://example.com%A0/", "input": "ftp://example.com%A0/",
// "base": "about:blank", "base": "about:blank",
// "failure": true "failure": true
// }, },
// { {
// "input": "https://example.com%80/", "input": "https://example.com%80/",
// "base": "about:blank", "base": "about:blank",
// "failure": true "failure": true
// }, },
// { {
// "input": "https://example.com%A0/", "input": "https://example.com%A0/",
// "base": "about:blank", "base": "about:blank",
// "failure": true "failure": true
// }, },
{ {
"input": "ftp://%e2%98%83", "input": "ftp://%e2%98%83",
"base": "about:blank", "base": "about:blank",

85
test/parallel/test-icu-punycode.js

@ -6,67 +6,36 @@ if (!common.hasIntl) {
return; return;
} }
const icu = getPunycode(); const icu = process.binding('icu');
const assert = require('assert'); const assert = require('assert');
function getPunycode() { const tests = require('../fixtures/url-idna.js');
try {
return process.binding('icu'); {
} catch (err) { for (const [i, { ascii, unicode }] of tests.valid.entries()) {
return undefined; assert.strictEqual(ascii, icu.toASCII(unicode), `toASCII(${i + 1})`);
assert.strictEqual(unicode, icu.toUnicode(ascii), `toUnicode(${i + 1})`);
assert.strictEqual(ascii, icu.toASCII(icu.toUnicode(ascii)),
`toASCII(toUnicode(${i + 1}))`);
assert.strictEqual(unicode, icu.toUnicode(icu.toASCII(unicode)),
`toUnicode(toASCII(${i + 1}))`);
} }
} }
// Credit for list: http://www.i18nguy.com/markup/idna-examples.html {
const tests = [ const errorRe = {
'افغانستا.icom.museum', ascii: /^Error: Cannot convert name to ASCII$/,
'الجزائر.icom.museum', unicode: /^Error: Cannot convert name to Unicode$/
'österreich.icom.museum', };
'বাংলাদেশ.icom.museum', const convertFunc = {
'беларусь.icom.museum', ascii: icu.toASCII,
'belgië.icom.museum', unicode: icu.toUnicode
'българия.icom.museum', };
'تشادر.icom.museum',
'中国.icom.museum',
'القمر.icom.museum',
'κυπρος.icom.museum',
'českárepublika.icom.museum',
'مصر.icom.museum',
'ελλάδα.icom.museum',
'magyarország.icom.museum',
'ísland.icom.museum',
'भारत.icom.museum',
'ايران.icom.museum',
'éire.icom.museum',
'איקו״ם.ישראל.museum',
'日本.icom.museum',
'الأردن.icom.museum',
'қазақстан.icom.museum',
'한국.icom.museum',
'кыргызстан.icom.museum',
'ລາວ.icom.museum',
'لبنان.icom.museum',
'македонија.icom.museum',
'موريتانيا.icom.museum',
'méxico.icom.museum',
'монголулс.icom.museum',
'المغرب.icom.museum',
'नेपाल.icom.museum',
'عمان.icom.museum',
'قطر.icom.museum',
'românia.icom.museum',
'россия.иком.museum',
'србијаицрнагора.иком.museum',
'இலங்கை.icom.museum',
'españa.icom.museum',
'ไทย.icom.museum',
'تونس.icom.museum',
'türkiye.icom.museum',
'украина.icom.museum',
'việtnam.icom.museum'
];
// Testing the roundtrip for (const [i, { url, mode }] of tests.invalid.entries()) {
tests.forEach((i) => { assert.throws(() => convertFunc[mode](url), errorRe[mode],
assert.strictEqual(i, icu.toUnicode(icu.toASCII(i))); `Invalid case ${i + 1}`);
}); assert.doesNotThrow(() => convertFunc[mode](url, true),
`Invalid case ${i + 1} in lenient mode`);
}
}

36
test/parallel/test-whatwg-url-domainto.js

@ -0,0 +1,36 @@
'use strict';
const common = require('../common');
if (!common.hasIntl) {
common.skip('missing Intl');
return;
}
const assert = require('assert');
const { domainToASCII, domainToUnicode } = require('url');
// Tests below are not from WPT.
const tests = require('../fixtures/url-idna.js');
{
for (const [i, { ascii, unicode }] of tests.valid.entries()) {
assert.strictEqual(ascii, domainToASCII(unicode),
`domainToASCII(${i + 1})`);
assert.strictEqual(unicode, domainToUnicode(ascii),
`domainToUnicode(${i + 1})`);
assert.strictEqual(ascii, domainToASCII(domainToUnicode(ascii)),
`domainToASCII(domainToUnicode(${i + 1}))`);
assert.strictEqual(unicode, domainToUnicode(domainToASCII(unicode)),
`domainToUnicode(domainToASCII(${i + 1}))`);
}
}
{
const convertFunc = {
ascii: domainToASCII,
unicode: domainToUnicode
};
for (const [i, { url, mode }] of tests.invalid.entries())
assert.strictEqual(convertFunc[mode](url), '', `Invalid case ${i + 1}`);
}
Loading…
Cancel
Save