From 6581e84949eb0db1a97513098c1413be433419ee Mon Sep 17 00:00:00 2001
From: Rick Waldron <waldron.rick@gmail.com>
Date: Wed, 3 Oct 2018 10:24:38 -0400
Subject: [PATCH] Intl.Locale: constructor-options-*.js fixups (#1798)

---
 .../Locale/constructor-locale-object.js       |  20 ++-
 .../Locale/constructor-newtarget-undefined.js |   4 +-
 .../Locale/constructor-non-iana-canon.js      |  24 +++-
 .../constructor-options-calendar-invalid.js   |   6 +-
 .../constructor-options-calendar-valid.js     |   9 +-
 .../constructor-options-casefirst-invalid.js  |   6 +-
 .../constructor-options-casefirst-valid.js    |  24 ++--
 .../constructor-options-collation-invalid.js  |   2 +-
 .../constructor-options-collation-valid.js    |  10 +-
 .../constructor-options-hourcycle-invalid.js  |   6 +-
 .../constructor-options-hourcycle-valid.js    |  17 ++-
 ...structor-options-language-grandfathered.js |  49 +++----
 .../constructor-options-language-invalid.js   |   6 +-
 ...ructor-options-language-valid-undefined.js |  40 ++++++
 .../constructor-options-language-valid.js     |  21 +--
 ...tructor-options-numberingsystem-invalid.js |   6 +-
 ...nstructor-options-numberingsystem-valid.js |   9 +-
 .../constructor-options-numeric-undefined.js  |   3 +
 .../constructor-options-numeric-valid.js      |  16 ++-
 .../constructor-options-region-invalid.js     |   6 +-
 .../constructor-options-region-valid.js       |   8 +-
 .../constructor-options-script-invalid.js     |   6 +-
 ...structor-options-script-valid-undefined.js |  48 +++++++
 .../constructor-options-script-valid.js       |  19 ++-
 .../constructor-options-throwing-getters.js   |   3 +-
 .../intl402/Locale/constructor-parse-twice.js | 131 +++++++++---------
 .../Locale/constructor-tag-tostring.js        |   5 +-
 test/intl402/Locale/constructor-tag.js        |  48 ++++---
 .../Locale/constructor-unicode-ext-invalid.js |  23 +--
 .../Locale/constructor-unicode-ext-valid.js   |   6 +-
 30 files changed, 349 insertions(+), 232 deletions(-)
 create mode 100644 test/intl402/Locale/constructor-options-language-valid-undefined.js
 create mode 100644 test/intl402/Locale/constructor-options-script-valid-undefined.js

diff --git a/test/intl402/Locale/constructor-locale-object.js b/test/intl402/Locale/constructor-locale-object.js
index 201b19dfad..3a21c65613 100644
--- a/test/intl402/Locale/constructor-locale-object.js
+++ b/test/intl402/Locale/constructor-locale-object.js
@@ -15,15 +15,23 @@ features: [Intl.Locale]
 const enUS = new Intl.Locale("en-US");
 const enGB = new Intl.Locale(enUS, {region: "GB"});
 
-assert.sameValue(enUS.toString(), "en-US");
-assert.sameValue(enGB.toString(), "en-GB");
+assert.sameValue(enUS.toString(), "en-US", 'enUS.toString() returns "en-US"');
+assert.sameValue(enGB.toString(), "en-GB", 'enGB.toString() returns "en-GB"');
 
 // Pass Intl.Locale object and replace Unicode extension keyword.
 const zhUnihan = new Intl.Locale("zh-u-co-unihan");
 const zhZhuyin = new Intl.Locale(zhUnihan, {collation: "zhuyin"});
 
-assert.sameValue(zhUnihan.toString(), "zh-u-co-unihan");
-assert.sameValue(zhZhuyin.toString(), "zh-u-co-zhuyin");
+assert.sameValue(
+  zhUnihan.toString(),
+  "zh-u-co-unihan",
+  'zhUnihan.toString() returns "zh-u-co-unihan"'
+);
+assert.sameValue(
+  zhZhuyin.toString(),
+  "zh-u-co-zhuyin",
+  'zhZhuyin.toString() returns "zh-u-co-zhuyin"'
+);
 
-assert.sameValue(zhUnihan.collation, "unihan");
-assert.sameValue(zhZhuyin.collation, "zhuyin");
+assert.sameValue(zhUnihan.collation, "unihan", 'The value of zhUnihan.collation is "unihan"');
+assert.sameValue(zhZhuyin.collation, "zhuyin", 'The value of zhZhuyin.collation is "zhuyin"');
diff --git a/test/intl402/Locale/constructor-newtarget-undefined.js b/test/intl402/Locale/constructor-newtarget-undefined.js
index e24be35be4..e8e542976d 100644
--- a/test/intl402/Locale/constructor-newtarget-undefined.js
+++ b/test/intl402/Locale/constructor-newtarget-undefined.js
@@ -14,8 +14,8 @@ features: [Intl.Locale]
 
 assert.throws(TypeError, function() {
   Intl.Locale();
-});
+}, 'Intl.Locale() throws TypeError');
 
 assert.throws(TypeError, function() {
   Intl.Locale("en");
-});
+}, 'Intl.Locale("en") throws TypeError');
diff --git a/test/intl402/Locale/constructor-non-iana-canon.js b/test/intl402/Locale/constructor-non-iana-canon.js
index 715b08ccbc..ded2af1c89 100644
--- a/test/intl402/Locale/constructor-non-iana-canon.js
+++ b/test/intl402/Locale/constructor-non-iana-canon.js
@@ -75,10 +75,26 @@ var testData = [
 ];
 
 for (const {tag, canonical = tag, maximized = canonical, minimized = canonical} of testData) {
-    assert.sameValue(Intl.getCanonicalLocales(tag)[0], canonical);
+    assert.sameValue(
+      Intl.getCanonicalLocales(tag)[0],
+      canonical,
+      'The value of Intl.getCanonicalLocales(tag)[0] equals the value of `canonical`'
+    );
 
     const loc = new Intl.Locale(tag);
-    assert.sameValue(loc.toString(), canonical);
-    assert.sameValue(loc.maximize().toString(), maximized);
-    assert.sameValue(loc.minimize().toString(), minimized);
+    assert.sameValue(
+      new Intl.Locale(tag).toString(),
+      canonical,
+      `new Intl.Locale("${tag}").toString() returns "${canonical}"`
+    );
+    assert.sameValue(
+      new Intl.Locale(tag).maximize().toString(),
+      maximized,
+      `new Intl.Locale("${tag}").maximize().toString() returns "${maximized}"`
+    );
+    assert.sameValue(
+      new Intl.Locale(tag).minimize().toString(),
+      minimized,
+      `new Intl.Locale("${tag}").minimize().toString() returns "${minimized}"`
+    );
 }
diff --git a/test/intl402/Locale/constructor-options-calendar-invalid.js b/test/intl402/Locale/constructor-options-calendar-invalid.js
index 7722a2eced..b0b02b8f88 100644
--- a/test/intl402/Locale/constructor-options-calendar-invalid.js
+++ b/test/intl402/Locale/constructor-options-calendar-invalid.js
@@ -29,8 +29,8 @@ const invalidCalendarOptions = [
   "abcdefghi",
   "abc-abcdefghi",
 ];
-for (const invalidCalendarOption of invalidCalendarOptions) {
+for (const calendar of invalidCalendarOptions) {
   assert.throws(RangeError, function() {
-    new Intl.Locale("en", {calendar: invalidCalendarOption});
-  }, `${invalidCalendarOption} is an invalid calendar option value`);
+    new Intl.Locale("en", {calendar});
+  }, `new Intl.Locale("en", {calendar: "${calendar}"}) throws RangeError`);
 }
diff --git a/test/intl402/Locale/constructor-options-calendar-valid.js b/test/intl402/Locale/constructor-options-calendar-valid.js
index fbd4f6d741..5701ac9846 100644
--- a/test/intl402/Locale/constructor-options-calendar-valid.js
+++ b/test/intl402/Locale/constructor-options-calendar-valid.js
@@ -28,15 +28,14 @@ const validCalendarOptions = [
   ["1234abcd-abc123", "en-u-ca-1234abcd-abc123"],
 ];
 for (const [calendar, expected] of validCalendarOptions) {
-  let options = { calendar };
   assert.sameValue(
-    new Intl.Locale('en', options).toString(),
+    new Intl.Locale('en', { calendar }).toString(),
     expected,
-    `new Intl.Locale('en', options).toString() equals the value of ${expected}`
+    `new Intl.Locale('en', { calendar: "${calendar}" }).toString() returns "${expected}"`
   );
   assert.sameValue(
-    new Intl.Locale('en-u-ca-gregory', options).toString(),
+    new Intl.Locale('en-u-ca-gregory', { calendar }).toString(),
     expected,
-    `new Intl.Locale('en-u-ca-gregory', options).toString() equals the value of ${expected}`
+    `new Intl.Locale('en-u-ca-gregory', { calendar: "${calendar}" }).toString() returns "${expected}"`
   );
 }
diff --git a/test/intl402/Locale/constructor-options-casefirst-invalid.js b/test/intl402/Locale/constructor-options-casefirst-invalid.js
index cf4b9c4524..d4863bdd1e 100644
--- a/test/intl402/Locale/constructor-options-casefirst-invalid.js
+++ b/test/intl402/Locale/constructor-options-casefirst-invalid.js
@@ -30,8 +30,8 @@ const invalidCaseFirstOptions = [
   "true",
   { valueOf() { return false; } },
 ];
-for (const invalidCaseFirstOption of invalidCaseFirstOptions) {
+for (const caseFirst of invalidCaseFirstOptions) {
   assert.throws(RangeError, function() {
-    new Intl.Locale("en", {caseFirst: invalidCaseFirstOption});
-  }, `${invalidCaseFirstOption} is an invalid caseFirst option value`);
+    new Intl.Locale("en", {caseFirst});
+  }, `new Intl.Locale("en", {caseFirst: "${caseFirst}"}) throws RangeError`);
 }
diff --git a/test/intl402/Locale/constructor-options-casefirst-valid.js b/test/intl402/Locale/constructor-options-casefirst-valid.js
index 391734a68c..61848904c8 100644
--- a/test/intl402/Locale/constructor-options-casefirst-valid.js
+++ b/test/intl402/Locale/constructor-options-casefirst-valid.js
@@ -43,22 +43,24 @@ const validCaseFirstOptions = [
   { toString() { return false; } },
 ];
 for (const caseFirst of validCaseFirstOptions) {
-  const options = { caseFirst };
   const expected = String(caseFirst);
+  let expect = "en-u-kf-" + expected;
   assert.sameValue(
-    new Intl.Locale('en', options).toString(),
-    "en-u-kf-" + expected
+    new Intl.Locale('en', { caseFirst }).toString(),
+    expect,
+    `new Intl.Locale("en", { caseFirst: "${caseFirst}" }).toString() returns "${expect}"`
   );
 
+  expect = "en-u-kf-" + expected;
   assert.sameValue(
-    new Intl.Locale('en-u-kf-lower', options).toString(),
-    "en-u-kf-" + expected
+    new Intl.Locale('en-u-kf-lower', { caseFirst }).toString(),
+    expect,
+    `new Intl.Locale("en-u-kf-lower", { caseFirst: "${caseFirst}" }).toString() returns "${expect}"`
   );
 
-  if ("caseFirst" in Intl.Locale.prototype) {
-    assert.sameValue(
-      new Intl.Locale('en-u-kf-lower', options).caseFirst,
-      expected
-    );
-  }
+  assert.sameValue(
+    new Intl.Locale('en-u-kf-lower', { caseFirst }).caseFirst,
+    expected,
+    `new Intl.Locale("en-u-kf-lower", { caseFirst }).caseFirst equals "${expected}"`
+  );
 }
diff --git a/test/intl402/Locale/constructor-options-collation-invalid.js b/test/intl402/Locale/constructor-options-collation-invalid.js
index dadf41db1c..c4e6868605 100644
--- a/test/intl402/Locale/constructor-options-collation-invalid.js
+++ b/test/intl402/Locale/constructor-options-collation-invalid.js
@@ -30,5 +30,5 @@ const invalidCollationOptions = [
 for (const invalidCollationOption of invalidCollationOptions) {
   assert.throws(RangeError, function() {
     new Intl.Locale("en", {collation: invalidCollationOption});
-  }, `${invalidCollationOption} is an invalid collation option value`);
+  }, '`new Intl.Locale("en", {collation: invalidCollationOption})` throws RangeError');
 }
diff --git a/test/intl402/Locale/constructor-options-collation-valid.js b/test/intl402/Locale/constructor-options-collation-valid.js
index addfa9a167..64521cc3ab 100644
--- a/test/intl402/Locale/constructor-options-collation-valid.js
+++ b/test/intl402/Locale/constructor-options-collation-valid.js
@@ -48,15 +48,15 @@ const validCollationOptions = [
   ["1234abcd-abc123", "en-u-co-1234abcd-abc123"],
 ];
 for (const [collation, expected] of validCollationOptions) {
-  let options = { collation };
   assert.sameValue(
-    new Intl.Locale('en', options).toString(),
+    new Intl.Locale('en', {collation}).toString(),
     expected,
-    `new Intl.Locale('en', options).toString() equals the value of ${expected}`
+    `new Intl.Locale('en', {collation: "${collation}"}).toString() returns "${expected}"`
   );
+
   assert.sameValue(
-    new Intl.Locale('en-u-co-gregory', options).toString(),
+    new Intl.Locale('en-u-co-gregory', {collation}).toString(),
     expected,
-    `new Intl.Locale('en-u-co-gregory', options).toString() equals the value of ${expected}`
+    `new Intl.Locale('en-u-co-gregory', {collation: "${collation}"}).toString() returns "${expected}"`
   );
 }
diff --git a/test/intl402/Locale/constructor-options-hourcycle-invalid.js b/test/intl402/Locale/constructor-options-hourcycle-invalid.js
index 0749641d28..cce1139e58 100644
--- a/test/intl402/Locale/constructor-options-hourcycle-invalid.js
+++ b/test/intl402/Locale/constructor-options-hourcycle-invalid.js
@@ -36,8 +36,8 @@ const invalidHourCycleOptions = [
   "h12\0",
   "H12",
 ];
-for (const invalidHourCycleOption of invalidHourCycleOptions) {
+for (const hourCycle of invalidHourCycleOptions) {
   assert.throws(RangeError, function() {
-    new Intl.Locale("en", {hourCycle: invalidHourCycleOption});
-  }, `${invalidHourCycleOption} is an invalid hourCycle option value`);
+    new Intl.Locale("en", {hourCycle});
+  }, `new Intl.Locale("en", {hourCycle: "${hourCycle}"}) throws RangeError`);
 }
diff --git a/test/intl402/Locale/constructor-options-hourcycle-valid.js b/test/intl402/Locale/constructor-options-hourcycle-valid.js
index 42fc7e16ef..7875c87a14 100644
--- a/test/intl402/Locale/constructor-options-hourcycle-valid.js
+++ b/test/intl402/Locale/constructor-options-hourcycle-valid.js
@@ -43,31 +43,30 @@ const validHourCycleOptions = [
   { toString() { return 'h24'; } },
 ];
 for (const hourCycle of validHourCycleOptions) {
-  const options = { hourCycle };
   const expected = String(hourCycle);
   let expect = 'en-u-hc-' + expected;
 
   assert.sameValue(
-    new Intl.Locale('en', options).toString(),
+    new Intl.Locale('en', {hourCycle}).toString(),
     expect,
-    `new Intl.Locale('en', options).toString() equals the value of ${expect}`
+    `new Intl.Locale("en", {hourCycle: "${hourCycle}"}).toString() returns "${expect}"`
   );
 
   assert.sameValue(
-    new Intl.Locale('en-u-hc-h00', options).toString(),
+    new Intl.Locale('en-u-hc-h00', {hourCycle}).toString(),
     expect,
-    `new Intl.Locale('en-u-hc-h00', options).toString() equals the value of ${expect}`
+    `new Intl.Locale("en-u-hc-h00", {hourCycle: "${hourCycle}"}).toString() returns "${expect}"`
   );
 
   assert.sameValue(
-    new Intl.Locale('en-u-hc-h12', options).toString(),
+    new Intl.Locale('en-u-hc-h12', {hourCycle}).toString(),
     expect,
-    `new Intl.Locale('en-u-hc-h12', options).toString() equals the value of ${expect}`
+    `new Intl.Locale("en-u-hc-h12", {hourCycle: "${hourCycle}"}).toString() returns "${expect}"`
   );
 
   assert.sameValue(
-    new Intl.Locale('en-u-hc-h00', options).hourCycle,
+    new Intl.Locale('en-u-hc-h00', {hourCycle}).hourCycle,
     expected,
-    `new Intl.Locale('en-u-hc-h00', options).hourCycle equals the value of ${expected}`
+    `new Intl.Locale("en-u-hc-h00", {hourCycle: "${hourCycle}"}).hourCycle equals "${expected}"`
   );
 }
diff --git a/test/intl402/Locale/constructor-options-language-grandfathered.js b/test/intl402/Locale/constructor-options-language-grandfathered.js
index f3dfc8d11e..6d54a0bc95 100644
--- a/test/intl402/Locale/constructor-options-language-grandfathered.js
+++ b/test/intl402/Locale/constructor-options-language-grandfathered.js
@@ -4,39 +4,30 @@
 /*---
 esid: sec-intl.locale
 description: >
-    Checks error cases for the options argument to the Locale
-    constructor.
+  Checks error cases for the options argument to the Locale
+  constructor.
 info: |
-    ApplyOptionsToTag( tag, options )
-    ...
-    3. Let language be ? GetOption(options, "language", "string", undefined, undefined).
-    4. If language is not undefined, then
-        a. If language does not match the language production, throw a RangeError exception.
-        b. If language matches the grandfathered production, throw a RangeError exception.
-    ...
+  ApplyOptionsToTag( tag, options )
+  ...
+  3. Let language be ? GetOption(options, "language", "string", undefined, undefined).
+  4. If language is not undefined, then
+    a. If language does not match the language production, throw a RangeError exception.
+    b. If language matches the grandfathered production, throw a RangeError exception.
+  ...
 
 features: [Intl.Locale]
 ---*/
 
-const testData = [
-    {
-        tag: "nb",
-        options: {
-            language: "no-bok",
-        },
-    },
+assert.throws(RangeError, function() {
+  new Intl.Locale("nb", {
+    language: "no-bok",
+  });
+}, `new Intl.Locale("nb", {language: "no-bok"}) throws RangeError`);
 
-    {
-        tag: "nb",
-        options: {
-            language: "no-bok",
-            region: "NO",
-        },
-    },
-];
+assert.throws(RangeError, function() {
+  new Intl.Locale("nb", {
+    language: "no-bok",
+    region: "NO",
+  });
+}, `new Intl.Locale("nb", {language: "no-bok", region: "NO"}) throws RangeError`);
 
-for (const {tag, options} of testData) {
-    assert.throws(RangeError, function() {
-        new Intl.Locale(tag, options);
-    });
-}
diff --git a/test/intl402/Locale/constructor-options-language-invalid.js b/test/intl402/Locale/constructor-options-language-invalid.js
index 5c593becd8..fcc424fbd1 100644
--- a/test/intl402/Locale/constructor-options-language-invalid.js
+++ b/test/intl402/Locale/constructor-options-language-invalid.js
@@ -62,8 +62,8 @@ const invalidLanguageOptions = [
 
   7,
 ];
-for (const invalidLanguageOption of invalidLanguageOptions) {
+for (const language of invalidLanguageOptions) {
   assert.throws(RangeError, function() {
-    new Intl.Locale("en", {language: invalidLanguageOption});
-  }, `${invalidLanguageOption} is an invalid language option value`);
+    new Intl.Locale("en", {language});
+  }, `new Intl.Locale("en", {language: "${language}"}) throws RangeError`);
 }
diff --git a/test/intl402/Locale/constructor-options-language-valid-undefined.js b/test/intl402/Locale/constructor-options-language-valid-undefined.js
new file mode 100644
index 0000000000..08b044abd2
--- /dev/null
+++ b/test/intl402/Locale/constructor-options-language-valid-undefined.js
@@ -0,0 +1,40 @@
+// Copyright 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.locale
+description: >
+    Verify valid language option values (undefined)
+info: |
+    Intl.Locale( tag [, options] )
+    10. If options is undefined, then
+    11. Else
+        a. Let options be ? ToObject(options).
+    12. Set tag to ? ApplyOptionsToTag(tag, options).
+
+    ApplyOptionsToTag( tag, options )
+    ...
+    9. If tag matches neither the privateuse nor the grandfathered production, then
+        b. If language is not undefined, then
+            i. Set tag to tag with the substring corresponding to the language production replaced by the string language.
+
+features: [Intl.Locale]
+---*/
+
+assert.sameValue(
+  new Intl.Locale('en', {language: undefined}).toString(),
+  'en',
+  `new Intl.Locale('en', {language: undefined}).toString() returns "en"`
+);
+
+assert.sameValue(
+  new Intl.Locale('en-US', {language: undefined}).toString(),
+  'en-US',
+  `new Intl.Locale('en-US', {language: undefined}).toString() returns "en-US"`
+);
+
+assert.sameValue(
+  new Intl.Locale('en-els', {language: undefined}).toString(),
+  'en-els',
+  `new Intl.Locale('en-els', {language: undefined}).toString() returns "en-els"`
+);
diff --git a/test/intl402/Locale/constructor-options-language-valid.js b/test/intl402/Locale/constructor-options-language-valid.js
index b07f96619b..6b7d405853 100644
--- a/test/intl402/Locale/constructor-options-language-valid.js
+++ b/test/intl402/Locale/constructor-options-language-valid.js
@@ -4,8 +4,7 @@
 /*---
 esid: sec-intl.locale
 description: >
-    Checks error cases for the options argument to the Locale
-    constructor.
+    Verify valid language option values (various)
 info: |
     Intl.Locale( tag [, options] )
     10. If options is undefined, then
@@ -23,38 +22,32 @@ features: [Intl.Locale]
 ---*/
 
 const validLanguageOptions = [
-  [undefined, undefined],
   [null, 'null'],
   ['zh-cmn', 'cmn'],
   ['ZH-CMN', 'cmn'],
   ['abcd', 'abcd'],
-  ['abcde', 'abcde'],
-  ['abcdef', 'abcdef'],
-  ['abcdefg', 'abcdefg'],
-  ['abcdefgh', 'abcdefgh'],
   [{ toString() { return 'de' } }, 'de'],
 ];
 for (const [language, expected] of validLanguageOptions) {
-  let options = { language };
   let expect = expected || 'en';
 
   assert.sameValue(
-    new Intl.Locale('en', options).toString(),
+    new Intl.Locale('en', {language}).toString(),
     expect,
-    `new Intl.Locale('en', options).toString() equals the value of ${expect}`
+    `new Intl.Locale('en', {language: "${language}"}).toString() returns "${expect}"`
   );
 
   expect = (expected || 'en') + '-US';
   assert.sameValue(
-    new Intl.Locale('en-US', options).toString(),
+    new Intl.Locale('en-US', {language}).toString(),
     expect,
-    `new Intl.Locale('en-US', options).toString() equals the value of ${expect}`
+    `new Intl.Locale('en-US', {language: "${language}"}).toString() returns "${expect}"`
   );
 
   expect = expected || 'en-els';
   assert.sameValue(
-    new Intl.Locale('en-els', options).toString(),
+    new Intl.Locale('en-els', {language}).toString(),
     expect,
-    `new Intl.Locale('en-els', options).toString() equals the value of ${expect}`
+    `new Intl.Locale('en-els', {language: "${language}"}).toString() returns "${expect}"`
   );
 }
diff --git a/test/intl402/Locale/constructor-options-numberingsystem-invalid.js b/test/intl402/Locale/constructor-options-numberingsystem-invalid.js
index 742a9ac483..ac0b5c4c8f 100644
--- a/test/intl402/Locale/constructor-options-numberingsystem-invalid.js
+++ b/test/intl402/Locale/constructor-options-numberingsystem-invalid.js
@@ -34,8 +34,8 @@ const invalidNumberingSystemOptions = [
   "latn-ca-",
   "latn-ca-gregory",
 ];
-for (const invalidNumberingSystemOption of invalidNumberingSystemOptions) {
+for (const numberingSystem of invalidNumberingSystemOptions) {
   assert.throws(RangeError, function() {
-    new Intl.Locale("en", {numberingSystem: invalidNumberingSystemOption});
-  }, `${invalidNumberingSystemOption} is an invalid numberingSystem option value`);
+    new Intl.Locale('en', {numberingSystem});
+  }, `new Intl.Locale("en", {numberingSystem: "${numberingSystem}"}) throws RangeError`);
 }
diff --git a/test/intl402/Locale/constructor-options-numberingsystem-valid.js b/test/intl402/Locale/constructor-options-numberingsystem-valid.js
index 5ad3716adf..bfd96fc0b9 100644
--- a/test/intl402/Locale/constructor-options-numberingsystem-valid.js
+++ b/test/intl402/Locale/constructor-options-numberingsystem-valid.js
@@ -48,15 +48,14 @@ const validNumberingSystemOptions = [
   ["1234abcd-abc123", "en-u-nu-1234abcd-abc123"],
 ];
 for (const [numberingSystem, expected] of validNumberingSystemOptions) {
-  let options = { numberingSystem };
   assert.sameValue(
-    new Intl.Locale('en', options).toString(),
+    new Intl.Locale('en', { numberingSystem }).toString(),
     expected,
-    `new Intl.Locale('en', options).toString() equals the value of ${expected}`
+    `new Intl.Locale("en", { numberingSystem: ${numberingSystem} }).toString() returns "${expected}"`
   );
   assert.sameValue(
-    new Intl.Locale('en-u-nu-latn', options).toString(),
+    new Intl.Locale('en-u-nu-latn', { numberingSystem }).toString(),
     expected,
-    `new Intl.Locale('en-u-nu-latn', options).toString() equals the value of ${expected}`
+    `new Intl.Locale("en-u-nu-latn", { numberingSystem: ${numberingSystem} }).toString() returns "${expected}"`
   );
 }
diff --git a/test/intl402/Locale/constructor-options-numeric-undefined.js b/test/intl402/Locale/constructor-options-numeric-undefined.js
index fa4251655c..ee3c787bfa 100644
--- a/test/intl402/Locale/constructor-options-numeric-undefined.js
+++ b/test/intl402/Locale/constructor-options-numeric-undefined.js
@@ -38,14 +38,17 @@ const options = { numeric: undefined };
 assert.sameValue(
   new Intl.Locale('en', options).toString(),
   "en",
+  'new Intl.Locale("en", {numeric: undefined}).toString() returns "en"'
 );
 
 assert.sameValue(
   new Intl.Locale('en-u-kn-true', options).toString(),
   "en-u-kn-true",
+  'new Intl.Locale("en-u-kn-true", {numeric: undefined}).toString() returns "en-u-kn-true"'
 );
 
 assert.sameValue(
   new Intl.Locale('en-u-kf-lower', options).numeric,
   undefined,
+  'The value of new Intl.Locale("en-u-kf-lower", {numeric: undefined}).numeric equals `undefined`'
 );
diff --git a/test/intl402/Locale/constructor-options-numeric-valid.js b/test/intl402/Locale/constructor-options-numeric-valid.js
index ce3d1da15a..1f3979d83c 100644
--- a/test/intl402/Locale/constructor-options-numeric-valid.js
+++ b/test/intl402/Locale/constructor-options-numeric-valid.js
@@ -46,21 +46,23 @@ const validNumericOptions = [
   [{ valueOf() { return false; } }, true],
 ];
 for (const [numeric, expected] of validNumericOptions) {
-  let options = { numeric };
   let expect = `en-u-kn-${expected}`;
 
   assert.sameValue(
-    new Intl.Locale('en', options).toString(),
-    expect
+    new Intl.Locale('en', {numeric}).toString(),
+    expect,
+    `new Intl.Locale("en", {numeric: ${numeric}}).toString() returns "${expected}"`
   );
 
   assert.sameValue(
-    new Intl.Locale('en-u-kn-true', options).toString(),
-    expect
+    new Intl.Locale('en-u-kn-true', {numeric}).toString(),
+    expect,
+    `new Intl.Locale("en-u-kn-true", {numeric: ${numeric}}).toString() returns "${expected}"`
   );
 
   assert.sameValue(
-    new Intl.Locale('en-u-kf-lower', options).numeric,
-    expected
+    new Intl.Locale('en-u-kf-lower', {numeric}).numeric,
+    String(expected),
+    `new Intl.Locale("en-u-kf-lower", {numeric: ${numeric}}).numeric equals "${expected}"`
   );
 }
diff --git a/test/intl402/Locale/constructor-options-region-invalid.js b/test/intl402/Locale/constructor-options-region-invalid.js
index 6939c225b9..dc72485b0b 100644
--- a/test/intl402/Locale/constructor-options-region-invalid.js
+++ b/test/intl402/Locale/constructor-options-region-invalid.js
@@ -49,8 +49,8 @@ const invalidRegionOptions = [
 
   7,
 ];
-for (const invalidRegionOption of invalidRegionOptions) {
+for (const region of invalidRegionOptions) {
   assert.throws(RangeError, function() {
-    new Intl.Locale("en", {region: invalidRegionOption});
-  }, `${invalidRegionOption} is an invalid region option value`);
+    new Intl.Locale("en", {region});
+  }, `new Intl.Locale("en", {region: "${region}"}) throws RangeError`);
 }
diff --git a/test/intl402/Locale/constructor-options-region-valid.js b/test/intl402/Locale/constructor-options-region-valid.js
index f9cb7eaddf..863d0c81b1 100644
--- a/test/intl402/Locale/constructor-options-region-valid.js
+++ b/test/intl402/Locale/constructor-options-region-valid.js
@@ -41,27 +41,27 @@ for (const [region, expected] of validRegionOptions) {
   assert.sameValue(
     new Intl.Locale('en', options).toString(),
     expect,
-    `new Intl.Locale('en', options).toString() equals the value of ${expect}`
+    `new Intl.Locale('en', {region: "${region}"}).toString() returns "${expect}"`
   );
 
   expect = expected || 'en-US';
   assert.sameValue(
     new Intl.Locale('en-US', options).toString(),
     expect,
-    `new Intl.Locale('en-US', options).toString() equals the value of ${expect}`
+    `new Intl.Locale('en-US', {region: "${region}"}).toString() returns "${expect}"`
   );
 
   expect = (expected || 'en') + '-u-ca-gregory';
   assert.sameValue(
     new Intl.Locale('en-u-ca-gregory', options).toString(),
     expect,
-    `new Intl.Locale('en-u-ca-gregory', options).toString() equals the value of ${expect}`
+    `new Intl.Locale('en-u-ca-gregory', {region: "${region}"}).toString() returns "${expect}"`
   );
 
   expect = (expected || 'en-US') + '-u-ca-gregory';
   assert.sameValue(
     new Intl.Locale('en-US-u-ca-gregory', options).toString(),
     expect,
-    `new Intl.Locale('en-US-u-ca-gregory', options).toString() equals the value of ${expect}`
+    `new Intl.Locale('en-US-u-ca-gregory', {region: "${region}"}).toString() returns "${expect}"`
   );
 }
diff --git a/test/intl402/Locale/constructor-options-script-invalid.js b/test/intl402/Locale/constructor-options-script-invalid.js
index a736280d54..551cf31017 100644
--- a/test/intl402/Locale/constructor-options-script-invalid.js
+++ b/test/intl402/Locale/constructor-options-script-invalid.js
@@ -45,8 +45,8 @@ const invalidScriptOptions = [
 
   7,
 ];
-for (const invalidScriptOption of invalidScriptOptions) {
+for (const script of invalidScriptOptions) {
   assert.throws(RangeError, function() {
-    new Intl.Locale("en", {script: invalidScriptOption});
-  }, `${invalidScriptOption} is an invalid script option value`);
+    new Intl.Locale("en", {script});
+  }, `new Intl.Locale("en", {script: "${script}"}) throws RangeError`);
 }
diff --git a/test/intl402/Locale/constructor-options-script-valid-undefined.js b/test/intl402/Locale/constructor-options-script-valid-undefined.js
new file mode 100644
index 0000000000..6101c1fd15
--- /dev/null
+++ b/test/intl402/Locale/constructor-options-script-valid-undefined.js
@@ -0,0 +1,48 @@
+// Copyright 2018 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-intl.locale
+description: >
+    Verify valid script option values (undefined)
+info: |
+    Intl.Locale( tag [, options] )
+    10. If options is undefined, then
+    11. Else
+        a. Let options be ? ToObject(options).
+    12. Set tag to ? ApplyOptionsToTag(tag, options).
+
+    ApplyOptionsToTag( tag, options )
+    ...
+    5. Let script be ? GetOption(options, "script", "string", undefined, undefined).
+    ...
+    9. If tag matches neither the privateuse nor the grandfathered production, then
+      ...
+      c. If script is not undefined, then
+        i. If tag does not contain a script production, then
+          1. Set tag to the concatenation of the language production of tag, "-", script, and the rest of tag.
+        ii. Else,
+          1. Set tag to tag with the substring corresponding to the script production replaced by the string script.
+
+
+features: [Intl.Locale]
+---*/
+
+assert.sameValue(
+  new Intl.Locale('en', {script: undefined}).toString(),
+  'en',
+  `new Intl.Locale('en', {script: undefined}).toString() returns "en"`
+);
+
+assert.sameValue(
+  new Intl.Locale('en-DK', {script: undefined}).toString(),
+  'en-DK',
+  `new Intl.Locale('en-DK', {script: undefined}).toString() returns "en-DK"`
+);
+
+assert.sameValue(
+  new Intl.Locale('en-Cyrl', {script: undefined}).toString(),
+  'en-Cyrl',
+  `new Intl.Locale('en-Cyrl', {script: undefined}).toString() returns "en-Cyrl"`
+);
+
diff --git a/test/intl402/Locale/constructor-options-script-valid.js b/test/intl402/Locale/constructor-options-script-valid.js
index 54bd153a6c..52f033ec2e 100644
--- a/test/intl402/Locale/constructor-options-script-valid.js
+++ b/test/intl402/Locale/constructor-options-script-valid.js
@@ -4,10 +4,11 @@
 /*---
 esid: sec-intl.locale
 description: >
-    Checks error cases for the options argument to the Locale
-    constructor.
+    Verify valid language option values (various)
 info: |
     Intl.Locale( tag [, options] )
+    9. Else,
+        a. Let tag be ? ToString(tag).
     10. If options is undefined, then
     11. Else
         a. Let options be ? ToObject(options).
@@ -30,7 +31,6 @@ features: [Intl.Locale]
 ---*/
 
 const validScriptOptions = [
-  [undefined, undefined],
   [null, 'Null'],
   ['bali', 'Bali'],
   ['Bali', 'Bali'],
@@ -38,26 +38,25 @@ const validScriptOptions = [
   [{ toString() { return 'Brai' } }, 'Brai'],
 ];
 for (const [script, expected] of validScriptOptions) {
-  let options = { script };
   let expect = expected ? 'en-' + expected : 'en';
 
   assert.sameValue(
-    new Intl.Locale('en', options).toString(),
+    new Intl.Locale('en', { script }).toString(),
     expect,
-    `new Intl.Locale('en', options).toString() equals the value of ${expect}`
+    `new Intl.Locale("en", {script: "${script}"}).toString() returns "${expect}"`
   );
 
   expect = (expected ? ('en-' + expected) : 'en') + '-DK';
   assert.sameValue(
-    new Intl.Locale('en-DK', options).toString(),
+    new Intl.Locale('en-DK', { script }).toString(),
     expect,
-    `new Intl.Locale('en', options).toString() equals the value of ${expect}`
+    `new Intl.Locale("en-DK", {script: "${script}"}).toString() returns "${expect}"`
   );
 
   expect = expected ? ('en-' + expected) : 'en-Cyrl';
   assert.sameValue(
-    new Intl.Locale('en-Cyrl', options).toString(),
+    new Intl.Locale('en-Cyrl', { script }).toString(),
     expect,
-    `new Intl.Locale('en-Cyrl', options).toString() equals the value of ${expect}`
+    `new Intl.Locale("en-Cyrl", {script: "${script}"}).toString() returns "${expect}"`
   );
 }
diff --git a/test/intl402/Locale/constructor-options-throwing-getters.js b/test/intl402/Locale/constructor-options-throwing-getters.js
index d3011011aa..f82abd6221 100644
--- a/test/intl402/Locale/constructor-options-throwing-getters.js
+++ b/test/intl402/Locale/constructor-options-throwing-getters.js
@@ -28,5 +28,6 @@ for (const option of options) {
         throw new CustomError();
       }
     });
-  }, `Exception from ${option} getter should be propagated`);
+  },
+  `new Intl.Locale("en", {get ${option}() {throw new CustomError();}}) throws CustomError`);
 }
diff --git a/test/intl402/Locale/constructor-parse-twice.js b/test/intl402/Locale/constructor-parse-twice.js
index 0c9dde16c9..868bca3047 100644
--- a/test/intl402/Locale/constructor-parse-twice.js
+++ b/test/intl402/Locale/constructor-parse-twice.js
@@ -4,90 +4,93 @@
 /*---
 esid: sec-intl.locale
 description: >
-    Verifies the handling of options with grandfathered tags.
+  Verifies the handling of options with grandfathered tags.
 info: |
-    Intl.Locale( tag [, options] )
-    12. Set tag to ? ApplyOptionsToTag(tag, options).
-    14. Let calendar be ? GetOption(options, "calendar", "string", undefined, undefined).
-    16. Set opt.[[ca]] to calendar.
-    30. Let r be ! ApplyUnicodeExtensionToTag(tag, opt, relevantExtensionKeys).
+  Intl.Locale( tag [, options] )
+  12. Set tag to ? ApplyOptionsToTag(tag, options).
+  14. Let calendar be ? GetOption(options, "calendar", "string", undefined, undefined).
+  16. Set opt.[[ca]] to calendar.
+  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).
+  ApplyOptionsToTag( tag, options )
+  9. If tag matches neither the privateuse nor the grandfathered production, then
+  10. Return CanonicalizeLanguageTag(tag).
 features: [Intl.Locale]
 ---*/
 
 const testData = [
-    // Irregular grandfathered tags.
+  // 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 "u-ca-gregory".
-    {
-        tag: "en-GB-oed",
-        options: {
-            region: "US",
-            calendar: "gregory",
-        },
-        canonical: "en-GB-oxendict-u-ca-gregory",
+  // "en-GB-oed" is a grandfathered tag, so we can't add "US". After it is
+  // canonicalized to "en-GB-oxendict" we can append "u-ca-gregory".
+  {
+    tag: "en-GB-oed",
+    options: {
+      region: "US",
+      calendar: "gregory",
     },
+    canonical: "en-GB-oxendict-u-ca-gregory",
+  },
 
-    // Canonicalized version of the above, which we can add "US" to.
-    {
-        tag: "en-GB-oxendict",
-        options: {
-            region: "US",
-            calendar: "gregory",
-        },
-        canonical: "en-US-oxendict-u-ca-gregory",
+  // Canonicalized version of the above, which we can add "US" to.
+  {
+    tag: "en-GB-oxendict",
+    options: {
+      region: "US",
+      calendar: "gregory",
     },
+    canonical: "en-US-oxendict-u-ca-gregory",
+  },
 
-    // Regular grandfathered tags.
+  // Regular grandfathered tags.
 
-    // "no-bok" is a grandfathered, so "NO"/"SE" isn't added. After
-    // canonicalization we can append "u-ca-gregory".
-    {
-        tag: "no-bok",
-        options: {
-            region: "NO",
-            calendar: "gregory",
-        },
-        canonical: "nb-u-ca-gregory",
+  // "no-bok" is a grandfathered, so "NO"/"SE" isn't added. After
+  // canonicalization we can append "u-ca-gregory".
+  {
+    tag: "no-bok",
+    options: {
+      region: "NO",
+      calendar: "gregory",
     },
+    canonical: "nb-u-ca-gregory",
+  },
 
-    {
-        tag: "no-bok",
-        options: {
-            region: "SE",
-            calendar: "gregory",
-        },
-        canonical: "nb-u-ca-gregory",
+  {
+    tag: "no-bok",
+    options: {
+      region: "SE",
+      calendar: "gregory",
     },
+    canonical: "nb-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-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",
+  // "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) {
-    const loc = new Intl.Locale(tag, options);
-    assert.sameValue(loc.toString(), canonical);
+  assert.sameValue(
+    new Intl.Locale(tag, options).toString(),
+    canonical,
+    `new Intl.Locale("${tag}", ${options}).toString() returns "${canonical}"`
+  );
 }
diff --git a/test/intl402/Locale/constructor-tag-tostring.js b/test/intl402/Locale/constructor-tag-tostring.js
index 733a5cd90d..f1e7ae25d1 100644
--- a/test/intl402/Locale/constructor-tag-tostring.js
+++ b/test/intl402/Locale/constructor-tag-tostring.js
@@ -31,5 +31,8 @@ const errors = [
 ];
 
 for (const input of errors) {
-  assert.throws(CustomError, function() { new Intl.Locale(input) });
+  assert.throws(CustomError, function() {
+    new Intl.Locale(input);
+  }),
+  `new Intl.Locale(${input}) throws CustomError`);
 }
diff --git a/test/intl402/Locale/constructor-tag.js b/test/intl402/Locale/constructor-tag.js
index bfd512415e..d75ec71d26 100644
--- a/test/intl402/Locale/constructor-tag.js
+++ b/test/intl402/Locale/constructor-tag.js
@@ -12,28 +12,34 @@ features: [Intl.Locale]
 ---*/
 
 const validLanguageTags = {
-    "eN": "en",
-    "en-gb": "en-GB",
-    "IT-LATN-iT": "it-Latn-IT",
-    "th-th-u-nu-thai": "th-TH-u-nu-thai",
-    "X-u-foo": "x-u-foo",
-    "en-x-u-foo": "en-x-u-foo",
-    "en-a-bar-x-u-foo": "en-a-bar-x-u-foo",
-    "en-x-u-foo-a-bar": "en-x-u-foo-a-bar",
-    "en-u-baz-a-bar-x-u-foo": "en-a-bar-u-baz-x-u-foo",
-    "Flob": "flob",
-    "ZORK": "zork",
-    "Blah-latn": "blah-Latn",
-    "QuuX-latn-us": "quux-Latn-US",
-    "SPAM-gb-x-Sausages-BACON-eggs": "spam-GB-x-sausages-bacon-eggs",
-    "DE-1996": "de-1996",
-    "sl-ROZAJ-BISKE-1994": "sl-rozaj-biske-1994",
-    "zh-latn-pinyin-pinyin2": "zh-Latn-pinyin-pinyin2",
+  "eN": "en",
+  "en-gb": "en-GB",
+  "IT-LATN-iT": "it-Latn-IT",
+  "th-th-u-nu-thai": "th-TH-u-nu-thai",
+  "X-u-foo": "x-u-foo",
+  "en-x-u-foo": "en-x-u-foo",
+  "en-a-bar-x-u-foo": "en-a-bar-x-u-foo",
+  "en-x-u-foo-a-bar": "en-x-u-foo-a-bar",
+  "en-u-baz-a-bar-x-u-foo": "en-a-bar-u-baz-x-u-foo",
+  "Flob": "flob",
+  "ZORK": "zork",
+  "Blah-latn": "blah-Latn",
+  "QuuX-latn-us": "quux-Latn-US",
+  "SPAM-gb-x-Sausages-BACON-eggs": "spam-GB-x-sausages-bacon-eggs",
+  "DE-1996": "de-1996",
+  "sl-ROZAJ-BISKE-1994": "sl-rozaj-biske-1994",
+  "zh-latn-pinyin-pinyin2": "zh-Latn-pinyin-pinyin2",
 };
 
 for (const [langtag, canonical] of Object.entries(validLanguageTags)) {
-    assert.sameValue(new Intl.Locale(canonical).toString(), canonical,
-                     `"${canonical}" should pass through unchanged`);
-    assert.sameValue(new Intl.Locale(langtag).toString(), canonical,
-                     `"${langtag}" should be canonicalized to "${canonical}`);
+  assert.sameValue(
+    new Intl.Locale(canonical).toString(),
+    canonical,
+    `new Intl.Locale("${canonical}").toString() returns "${canonical}"`
+  );
+  assert.sameValue(
+    new Intl.Locale(langtag).toString(),
+    canonical,
+    `new Intl.Locale("${langtag}").toString() returns "${canonical}"`
+  );
 }
diff --git a/test/intl402/Locale/constructor-unicode-ext-invalid.js b/test/intl402/Locale/constructor-unicode-ext-invalid.js
index 1f1cb08ce9..8129f40229 100644
--- a/test/intl402/Locale/constructor-unicode-ext-invalid.js
+++ b/test/intl402/Locale/constructor-unicode-ext-invalid.js
@@ -12,19 +12,20 @@ features: [Intl.Locale]
 ---*/
 
 const invalidLanguageTags = [
-    // Unicode extension sequence is incomplete.
-    "da-u",
-    "da-u-",
-    "da-u--",
-    "da-u-t-latn",
-    "da-u-x-priv",
+  // Unicode extension sequence is incomplete.
+  "da-u",
+  "da-u-",
+  "da-u--",
+  "da-u-t-latn",
+  "da-u-x-priv",
 
-    // Duplicate 'u' singleton.
-    "da-u-ca-gregory-u-ca-buddhist"
+  // Duplicate 'u' singleton.
+  "da-u-ca-gregory-u-ca-buddhist"
 ];
 
 for (const langtag of invalidLanguageTags) {
-    assert.throws(RangeError, function() {
-        new Intl.Locale(langtag)
-    });
+  assert.throws(RangeError, function() {
+    new Intl.Locale(langtag)
+  },
+  `new Intl.Locale("${langtag}") throws RangeError`);
 }
diff --git a/test/intl402/Locale/constructor-unicode-ext-valid.js b/test/intl402/Locale/constructor-unicode-ext-valid.js
index 55ed30cb8c..d3bebe25d1 100644
--- a/test/intl402/Locale/constructor-unicode-ext-valid.js
+++ b/test/intl402/Locale/constructor-unicode-ext-valid.js
@@ -30,5 +30,9 @@ const validLanguageTags = {
 };
 
 for (const [langtag, canonical] of Object.entries(validLanguageTags)) {
-    assert.sameValue(new Intl.Locale(langtag).toString(), canonical);
+    assert.sameValue(
+      new Intl.Locale(langtag).toString(),
+      canonical,
+      `new Intl.Locale("${langtag}").toString() returns "${canonical}"`
+    );
 }
-- 
GitLab