From b7c9c6c78b65f63df93650c11476225f38bcd1fa Mon Sep 17 00:00:00 2001
From: Frank Yung-Fong Tang <41213225+FrankYFTang@users.noreply.github.com>
Date: Thu, 24 Jan 2019 09:34:03 -0800
Subject: [PATCH] Remove unsupported irregular grandfathered tags. (#2029)

---
 .../intl402/Locale/constructor-parse-twice.js |  82 +++------
 .../Locale/extensions-grandfathered.js        |  60 ++-----
 test/intl402/Locale/getters-grandfathered.js  |  28 ++--
 .../Locale/likely-subtags-grandfathered.js    | 156 ++++++------------
 4 files changed, 100 insertions(+), 226 deletions(-)

diff --git a/test/intl402/Locale/constructor-parse-twice.js b/test/intl402/Locale/constructor-parse-twice.js
index 93e7e51efd..ddd3ccfc55 100644
--- a/test/intl402/Locale/constructor-parse-twice.js
+++ b/test/intl402/Locale/constructor-parse-twice.js
@@ -13,26 +13,22 @@ info: |
   30. Let r be ! ApplyUnicodeExtensionToTag(tag, opt, relevantExtensionKeys).
 
   ApplyOptionsToTag( tag, options )
-  9. If tag matches neither the privateuse nor the grandfathered production, then
-  10. Return CanonicalizeLanguageTag(tag).
+  ...
+  2. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception.
+
+  IsStructurallyValidLanguageTag ( locale )
+
+  The IsStructurallyValidLanguageTag abstract operation verifies that the
+  locale argument (which must be a String value)
+
+  represents a well-formed Unicode BCP 47 Locale Identifier" as specified in
+  Unicode Technical Standard 35 section 3.2, or successor,
+
 features: [Intl.Locale]
 ---*/
 
 const testData = [
-  // Irregular grandfathered tags.
-
-  // "en-GB-oed" is a grandfathered tag, so we can't add "US". After it is
-  // canonicalized to "en-GB-oxendict" we can append "US" and "u-ca-gregory".
-  {
-    tag: "en-GB-oed",
-    options: {
-      region: "US",
-      calendar: "gregory",
-    },
-    canonical: "en-US-oxendict-u-ca-gregory",
-  },
-
-  // Canonicalized version of the above, which we can add "US" to right away.
+  // Canonicalized version of "en-GB-oed", which we can add "US" to right away.
   {
     tag: "en-GB-oxendict",
     options: {
@@ -41,50 +37,6 @@ const testData = [
     },
     canonical: "en-US-oxendict-u-ca-gregory",
   },
-
-  // Regular grandfathered tags.
-
-  // "no-bok" is a grandfathered, so "NO"/"SE" isn't added. After
-  // canonicalization we can append "NO"/"SE" and "u-ca-gregory".
-  {
-    tag: "no-bok",
-    options: {
-      region: "NO",
-      calendar: "gregory",
-    },
-    canonical: "nb-NO-u-ca-gregory",
-  },
-
-  {
-    tag: "no-bok",
-    options: {
-      region: "SE",
-      calendar: "gregory",
-    },
-    canonical: "nb-SE-u-ca-gregory",
-  },
-
-  // "no-bok-NO" isn't a grandfathered tag, so we can replace "NO" with "SE"
-  // and can also append "u-ca-gregory".
-  {
-    tag: "no-bok-NO",
-    options: {
-      region: "SE",
-      calendar: "gregory",
-    },
-    canonical: "no-bok-SE-u-ca-gregory",
-  },
-
-  // "no-bok-SE" isn't a grandfathered tag, so we can replace "SE" with "NO"
-  // and can also append "u-ca-gregory".
-  {
-    tag: "no-bok-SE",
-    options: {
-      region: "NO",
-      calendar: "gregory",
-    },
-    canonical: "no-bok-NO-u-ca-gregory",
-  },
 ];
 
 for (const {tag, options, canonical} of testData) {
@@ -94,3 +46,13 @@ for (const {tag, options, canonical} of testData) {
     `new Intl.Locale("${tag}", ${options}).toString() returns "${canonical}"`
   );
 }
+
+assert.throws(RangeError, () =>
+    new Intl.Locale("no-bok", {region: "NO", calendar: "gregory"}));
+assert.throws(RangeError, () =>
+    new Intl.Locale("no-bok", {region: "SE", calendar: "gregory"}));
+assert.throws(RangeError, () =>
+    new Intl.Locale("no-bok-NO", {region: "SE", calendar: "gregory"}));
+assert.throws(RangeError, () =>
+    new Intl.Locale("no-bok-SE", {region: "NO", calendar: "gregory"}));
+
diff --git a/test/intl402/Locale/extensions-grandfathered.js b/test/intl402/Locale/extensions-grandfathered.js
index 096c8273f2..1ccc39cbb1 100644
--- a/test/intl402/Locale/extensions-grandfathered.js
+++ b/test/intl402/Locale/extensions-grandfathered.js
@@ -7,57 +7,21 @@ description: >
     Verifies handling of options with grandfathered tags.
 info: |
     ApplyOptionsToTag( tag, options )
-
-    ...
-    9. If tag matches neither the privateuse nor the grandfathered production, then
     ...
+    2. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception.
 
-    ApplyUnicodeExtensionToTag( tag, options, relevantExtensionKeys )
+    IsStructurallyValidLanguageTag ( locale )
 
-    ...
-    2. If tag matches the privateuse or the grandfathered production, then
-        a. Let result be a new Record.
-        b. Repeat for each element key of relevantExtensionKeys in List order,
-            i. Set result.[[<key>]] to undefined.
-        c. Set result.[[locale]] to tag.
-        d. Return result.
-    ...
-    7. Repeat for each element key of relevantExtensionKeys in List order,
-        e. Let optionsValue be options.[[<key>]].
-        f. If optionsValue is not undefined, then
-            ii. Let value be optionsValue.
-            iv. Else,
-                1. Append the Record{[[Key]]: key, [[Value]]: value} to keywords.
-    ...
+    The IsStructurallyValidLanguageTag abstract operation verifies that the
+    locale argument (which must be a String value)
+
+    represents a well-formed Unicode BCP 47 Locale Identifier" as specified in
+    Unicode Technical Standard 35 section 3.2, or successor,
 
 features: [Intl.Locale]
 ---*/
 
 const testData = [
-    // Irregular grandfathered without modern replacement.
-    {
-        tag: "i-default",
-        options: {
-            language: "fr",
-            script: "Cyrl",
-            region: "DE",
-            numberingSystem: "latn",
-        },
-        canonical: "fr-Cyrl-DE-u-nu-latn",
-    },
-
-    // Irregular grandfathered with modern replacement.
-    {
-        tag: "en-gb-oed",
-        options: {
-            language: "fr",
-            script: "Cyrl",
-            region: "US",
-            numberingSystem: "latn",
-        },
-        canonical: "fr-Cyrl-US-oxendict-u-nu-latn",
-    },
-
     // Regular grandfathered without modern replacement.
     {
         tag: "cel-gaulish",
@@ -91,3 +55,13 @@ for (const {tag, options, canonical} of testData) {
         assert.sameValue(loc[name], value);
     }
 }
+
+assert.throws(RangeError, () =>
+    new Intl.Locale("i-default",
+      {language: "fr", script: "Cyrl", region: "DE", numberingSystem: "latn"}
+      ));
+
+assert.throws(RangeError, () =>
+    new Intl.Locale("en-gb-oed",
+      {language: "fr", script: "Cyrl", region: "US", numberingSystem: "latn"}
+      ));
diff --git a/test/intl402/Locale/getters-grandfathered.js b/test/intl402/Locale/getters-grandfathered.js
index cd54fbd660..41d8cec851 100644
--- a/test/intl402/Locale/getters-grandfathered.js
+++ b/test/intl402/Locale/getters-grandfathered.js
@@ -7,29 +7,24 @@ description: >
     Verifies getters with grandfathered tags.
 info: |
     get Intl.Locale.prototype.baseName
-    4. If locale does not match the langtag production, return locale.
     5. Return the substring of locale corresponding to the
        language ["-" script] ["-" region] *("-" variant)
-       subsequence of the langtag grammar.
+       subsequence of the  unicode_language_id grammar.
 
     get Intl.Locale.prototype.language
-    4. If locale matches the privateuse or the grandfathered production, return locale.
+    5. Return the substring of locale corresponding to the
+       unicode_language_subtag production.
 
     get Intl.Locale.prototype.script
-    4. If locale matches the privateuse or the grandfathered production, return undefined.
+    6. Return the substring of locale corresponding to the
+       unicode_script_subtag production.
 
     get Intl.Locale.prototype.region
-    4. If locale matches the privateuse or the grandfathered production, return undefined.
+    6. Return the substring of locale corresponding to the unicode_region_subtag
+       production.
 features: [Intl.Locale]
 ---*/
 
-// Irregular grandfathered language tag.
-var loc = new Intl.Locale("i-default");
-assert.sameValue(loc.baseName, "i-default"); // Step 4.
-assert.sameValue(loc.language, "i-default");
-assert.sameValue(loc.script, undefined);
-assert.sameValue(loc.region, undefined);
-
 // Regular grandfathered language tag.
 var loc = new Intl.Locale("cel-gaulish");
 assert.sameValue(loc.baseName, "cel-gaulish"); // Step 5.
@@ -38,8 +33,7 @@ assert.sameValue(loc.script, undefined);
 assert.sameValue(loc.region, undefined);
 
 // Regular grandfathered language tag.
-var loc = new Intl.Locale("zh-min");
-assert.sameValue(loc.baseName, "zh-min"); // Step 5.
-assert.sameValue(loc.language, "zh-min");
-assert.sameValue(loc.script, undefined);
-assert.sameValue(loc.region, undefined);
+assert.throws(RangeError, () => new Intl.Locale("zh-min"));
+
+assert.throws(RangeError, () => new Intl.Locale("i-default"));
+
diff --git a/test/intl402/Locale/likely-subtags-grandfathered.js b/test/intl402/Locale/likely-subtags-grandfathered.js
index 2dcee94606..713cbd85c3 100644
--- a/test/intl402/Locale/likely-subtags-grandfathered.js
+++ b/test/intl402/Locale/likely-subtags-grandfathered.js
@@ -7,7 +7,26 @@ description: >
     Verifies canonicalization, minimization and maximization of specific tags.
 info: |
     ApplyOptionsToTag( tag, options )
-    10. Return CanonicalizeLanguageTag(tag).
+
+    2. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError exception.
+
+    9. Set tag to CanonicalizeLanguageTag(tag).
+
+    CanonicalizeLanguageTag( tag )
+
+    The CanonicalizeLanguageTag abstract operation returns the canonical and
+    case-regularized form of the locale argument (which must be a String value
+    that is a structurally valid Unicode BCP 47 Locale Identifier as verified by
+    the IsStructurallyValidLanguageTag abstract operation).
+
+    IsStructurallyValidLanguageTag ( locale )
+
+    The IsStructurallyValidLanguageTag abstract operation verifies that the
+    locale argument (which must be a String value)
+
+    represents a well-formed Unicode BCP 47 Locale Identifier" as specified in
+    Unicode Technical Standard 35 section 3.2, or successor,
+
 
     Intl.Locale.prototype.maximize ()
     3. Let maximal be the result of the Add Likely Subtags algorithm applied to loc.[[Locale]].
@@ -18,94 +37,27 @@ features: [Intl.Locale]
 ---*/
 
 const irregularGrandfathered = [
-    {
-        tag: "en-GB-oed",
-        canonical: "en-GB-oxendict",
-        maximized: "en-Latn-GB-oxendict",
-    },
-    {
-        tag: "i-ami",
-        canonical: "ami",
-    },
-    {
-        tag: "i-bnn",
-        canonical: "bnn",
-    },
-    {
-        tag: "i-default",
-        canonical: "i-default",
-    },
-    {
-        tag: "i-enochian",
-        canonical: "i-enochian",
-    },
-    {
-        tag: "i-hak",
-        canonical: "hak",
-        maximized: "hak-Hans-CN",
-    },
-    {
-        tag: "i-klingon",
-        canonical: "tlh",
-    },
-    {
-        tag: "i-lux",
-        canonical: "lb",
-        maximized: "lb-Latn-LU",
-    },
-    {
-        tag: "i-mingo",
-        canonical: "i-mingo",
-    },
-    {
-        tag: "i-navajo",
-        canonical: "nv",
-        maximized: "nv-Latn-US",
-    },
-    {
-        tag: "i-pwn",
-        canonical: "pwn",
-    },
-    {
-        tag: "i-tao",
-        canonical: "tao",
-    },
-    {
-        tag: "i-tay",
-        canonical: "tay",
-    },
-    {
-        tag: "i-tsu",
-        canonical: "tsu",
-    },
-    {
-        tag: "sgn-BE-FR",
-        canonical: "sfb",
-    },
-    {
-        tag: "sgn-BE-NL",
-        canonical: "vgt",
-    },
-    {
-        tag: "sgn-CH-DE",
-        canonical: "sgg",
-    },
+    "en-GB-oed",
+    "i-ami",
+    "i-bnn",
+    "i-default",
+    "i-enochian",
+    "i-hak",
+    "i-klingon",
+    "i-lux",
+    "i-mingo",
+    "i-navajo",
+    "i-pwn",
+    "i-tao",
+    "i-tay",
+    "i-tsu",
+    "sgn-BE-FR",
+    "sgn-BE-NL",
+    "sgn-CH-DE",
 ];
 
-for (const {tag, canonical, maximized = canonical, minimized = canonical} of irregularGrandfathered) {
-    assert.sameValue(Intl.getCanonicalLocales(tag)[0], canonical);
-
-    const loc = new Intl.Locale(tag);
-    assert.sameValue(loc.toString(), canonical);
-
-    assert.sameValue(loc.maximize().toString(), maximized);
-    assert.sameValue(loc.maximize().maximize().toString(), maximized);
-
-    assert.sameValue(loc.minimize().toString(), minimized);
-    assert.sameValue(loc.minimize().minimize().toString(), minimized);
-
-    assert.sameValue(loc.maximize().minimize().toString(), minimized);
-    assert.sameValue(loc.minimize().maximize().toString(), maximized);
+for (const tag of irregularGrandfathered) {
+    assert.throws(RangeError, () => new Intl.Locale(tag));
 }
 
 const regularGrandfathered = [
@@ -118,16 +70,6 @@ const regularGrandfathered = [
         tag: "cel-gaulish",
         canonical: "cel-gaulish",
     },
-    {
-        tag: "no-bok",
-        canonical: "nb",
-        maximized: "nb-Latn-NO",
-    },
-    {
-        tag: "no-nyn",
-        canonical: "nn",
-        maximized: "nn-Latn-NO",
-    },
     {
         tag: "zh-guoyu",
         canonical: "cmn",
@@ -137,15 +79,6 @@ const regularGrandfathered = [
         canonical: "hak",
         maximized: "hak-Hans-CN",
     },
-    {
-        tag: "zh-min",
-        canonical: "zh-min",
-    },
-    {
-        tag: "zh-min-nan",
-        canonical: "nan",
-        maximized: "nan-Hans-CN",
-    },
     {
         tag: "zh-xiang",
         canonical: "hsn",
@@ -169,6 +102,17 @@ for (const {tag, canonical, maximized = canonical, minimized = canonical} of reg
     assert.sameValue(loc.minimize().maximize().toString(), maximized);
 }
 
+const regularGrandfatheredWithExtLang = [
+    "no-bok",
+    "no-nyn",
+    "zh-min",
+    "zh-min-nan",
+];
+
+for (const tag of regularGrandfatheredWithExtLang) {
+    assert.throws(RangeError, () => new Intl.Locale(tag));
+}
+
 // Add constiants, extensions, and privateuse subtags to regular grandfathered
 // language tags and ensure it produces the "expected" result.
 const extras = [
-- 
GitLab