From d93e7b08e79341d256936d9c481978f2efd4f517 Mon Sep 17 00:00:00 2001 From: Mike Pennisi Date: Mon, 26 Jul 2021 22:16:18 -0400 Subject: [PATCH] Add tests for proposal, "Intl.DisplayNames v2" https://tc39.es/intl-displaynames-v2/ --- .../options-languagedisplay-abrupt-throws.js | 37 ++++++++++ .../options-languagedisplay-invalid-throws.js | 57 ++++++++++++++++ ...-languagedisplay-toString-abrupt-throws.js | 55 +++++++++++++++ .../options-languagedisplay-valid.js | 47 +++++++++++++ .../prototype/of/type-calendar-invalid.js | 45 ++++++++++++ .../prototype/of/type-calendar-valid.js | 32 +++++++++ .../of/type-datetimefield-invalid.js | 37 ++++++++++ .../prototype/of/type-datetimefield-valid.js | 22 ++++++ .../resolvedOptions/option-fallback.js | 1 + .../resolvedOptions/option-languagedisplay.js | 68 +++++++++++++++++++ .../prototype/resolvedOptions/option-style.js | 1 + .../prototype/resolvedOptions/option-type.js | 1 + 12 files changed, 403 insertions(+) create mode 100644 test/intl402/DisplayNames/options-languagedisplay-abrupt-throws.js create mode 100644 test/intl402/DisplayNames/options-languagedisplay-invalid-throws.js create mode 100644 test/intl402/DisplayNames/options-languagedisplay-toString-abrupt-throws.js create mode 100644 test/intl402/DisplayNames/options-languagedisplay-valid.js create mode 100644 test/intl402/DisplayNames/prototype/of/type-calendar-invalid.js create mode 100644 test/intl402/DisplayNames/prototype/of/type-calendar-valid.js create mode 100644 test/intl402/DisplayNames/prototype/of/type-datetimefield-invalid.js create mode 100644 test/intl402/DisplayNames/prototype/of/type-datetimefield-valid.js create mode 100644 test/intl402/DisplayNames/prototype/resolvedOptions/option-languagedisplay.js diff --git a/test/intl402/DisplayNames/options-languagedisplay-abrupt-throws.js b/test/intl402/DisplayNames/options-languagedisplay-abrupt-throws.js new file mode 100644 index 0000000000..f5ba5b5c23 --- /dev/null +++ b/test/intl402/DisplayNames/options-languagedisplay-abrupt-throws.js @@ -0,0 +1,37 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DisplayNames +description: Return abrupt completion from GetOption fallback +info: | + Intl.DisplayNames ( locales , options ) + + 1. If NewTarget is undefined, throw a TypeError exception. + 2. Let displayNames be ? OrdinaryCreateFromConstructor(NewTarget, "%DisplayNamesPrototype%", + « [[InitializedDisplayNames]], [[Locale]], [[Style]], [[Type]], [[Fallback]], [[Fields]] »). + ... + 4. Let options be ? ToObject(options). + ... + 12. Let type be ? GetOption(options, "type", "string", « "language", "region", "script", "currency" », undefined). + 13. If type is undefined, throw a TypeError exception. + ... + 24. Let languageDisplay be ? GetOption(options, "languageDisplay", "string", « "dialect", "standard" », "dialect"). + ... + + GetOption ( options, property, type, values, fallback ) + + 1. Let value be ? Get(options, property). + ... +features: [Intl.DisplayNames-v2] +locale: [en] +---*/ + +var options = { type: 'language' }; +Object.defineProperty(options, 'languageDisplay', { + get() { throw new Test262Error(); }, +}); + +assert.throws(Test262Error, () => { + new Intl.DisplayNames('en', options); +}); diff --git a/test/intl402/DisplayNames/options-languagedisplay-invalid-throws.js b/test/intl402/DisplayNames/options-languagedisplay-invalid-throws.js new file mode 100644 index 0000000000..49e9328f00 --- /dev/null +++ b/test/intl402/DisplayNames/options-languagedisplay-invalid-throws.js @@ -0,0 +1,57 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DisplayNames +description: > + Return abrupt completion from an invalid fallback option +info: | + Intl.DisplayNames ( locales , options ) + + 1. If NewTarget is undefined, throw a TypeError exception. + 2. Let displayNames be ? OrdinaryCreateFromConstructor(NewTarget, "%DisplayNamesPrototype%", + « [[InitializedDisplayNames]], [[Locale]], [[Style]], [[Type]], [[Fallback]], [[Fields]] »). + ... + 4. Let options be ? ToObject(options). + ... + 8. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit"). + ... + 12. Let type be ? GetOption(options, "type", "string", « "language", "region", "script", "currency" », "language"). + 13. If type is undefined, throw a TypeError exception. + ... + 24. Let languageDisplay be ? GetOption(options, "languageDisplay", "string", « "dialect", "standard" », "dialect"). + ... + + GetOption ( options, property, type, values, fallback ) + + 1. Let value be ? Get(options, property). + 2. If value is not undefined, then + ... + c. If type is "string", then + i. Let value be ? ToString(value). + d. If values is not undefined, then + i. If values does not contain an element equal to value, throw a RangeError exception. + ... +features: [Intl.DisplayNames-v2] +locale: [en] +---*/ + +assert.throws(RangeError, () => { + new Intl.DisplayNames('en', {languageDisplay: 'err', type: 'language'}); +}, 'err'); + +assert.throws(RangeError, () => { + new Intl.DisplayNames('en', {languageDisplay: 'standar', type: 'language'}); +}, 'standar, not standard'); + +assert.throws(RangeError, () => { + new Intl.DisplayNames('en', {languageDisplay: null, type: 'language'}); +}, 'null'); + +assert.throws(RangeError, () => { + new Intl.DisplayNames('en', {languageDisplay: '', type: 'language'}); +}, 'the empty string'); + +assert.throws(RangeError, () => { + new Intl.DisplayNames('en', {languageDisplay: ['dialect', 'standard'], type: 'language'}); +}, 'an array with the valid options is not necessarily valid'); diff --git a/test/intl402/DisplayNames/options-languagedisplay-toString-abrupt-throws.js b/test/intl402/DisplayNames/options-languagedisplay-toString-abrupt-throws.js new file mode 100644 index 0000000000..ed58b658dc --- /dev/null +++ b/test/intl402/DisplayNames/options-languagedisplay-toString-abrupt-throws.js @@ -0,0 +1,55 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DisplayNames +description: > + Return abrupt completion from GetOption fallback +info: | + Intl.DisplayNames ( locales , options ) + + 1. If NewTarget is undefined, throw a TypeError exception. + 2. Let displayNames be ? OrdinaryCreateFromConstructor(NewTarget, "%DisplayNamesPrototype%", + « [[InitializedDisplayNames]], [[Locale]], [[Style]], [[Type]], [[Fallback]], [[Fields]] »). + ... + 4. Let options be ? ToObject(options). + ... + 8. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit"). + ... + 24. Let languageDisplay be ? GetOption(options, "languageDisplay", "string", « "dialect", "standard" », "dialect"). + ... + + GetOption ( options, property, type, values, fallback ) + + 1. Let value be ? Get(options, property). + ... +features: [Intl.DisplayNames-v2, Symbol] +locale: [en] +---*/ + +assert.throws(Test262Error, () => { + new Intl.DisplayNames('en', { + type: 'language', languageDisplay: { toString() { throw new Test262Error(); }} + }); +}, 'from toString'); + +assert.throws(Test262Error, () => { + new Intl.DisplayNames('en', { + type: 'language', + languageDisplay: {toString: undefined, valueOf() {throw new Test262Error(); }} + }); +}, 'from valueOf'); + +assert.throws(Test262Error, () => { + new Intl.DisplayNames('en', { + type: 'language', + languageDisplay: { [Symbol.toPrimitive]() { throw new Test262Error(); } } + }); +}, 'from ToPrimitive'); + +assert.throws(TypeError, () => { + new Intl.DisplayNames('en', { + type: 'language', + languageDisplay: Symbol() + }); +}, 'symbol value'); diff --git a/test/intl402/DisplayNames/options-languagedisplay-valid.js b/test/intl402/DisplayNames/options-languagedisplay-valid.js new file mode 100644 index 0000000000..9c2c219af8 --- /dev/null +++ b/test/intl402/DisplayNames/options-languagedisplay-valid.js @@ -0,0 +1,47 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DisplayNames +description: Valid options for languageDisplay +info: | + Intl.DisplayNames ( locales , options ) + + 1. If NewTarget is undefined, throw a TypeError exception. + 2. Let displayNames be ? OrdinaryCreateFromConstructor(NewTarget, "%DisplayNamesPrototype%", + « [[InitializedDisplayNames]], [[Locale]], [[Style]], [[Type]], [[Fallback]], [[Fields]] »). + ... + 4. Let options be ? ToObject(options). + ... + 8. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit"). + ... + 10. Let style be ? GetOption(options, "style", "string", « "narrow", "short", "long" », "long"). + ... + 12. Let type be ? GetOption(options, "type", "string", « "language", "region", "script", "currency" », undefined). + 13. If type is undefined, throw a TypeError exception. + ... + 24. Let languageDisplay be ? GetOption(options, "languageDisplay", "string", « "dialect", "standard" », "dialect"). + ... + + GetOption ( options, property, type, values, fallback ) + + 1. Let value be ? Get(options, property). + ... +features: [Intl.DisplayNames-v2] +locale: [en] +---*/ + +// results for option values verified in the tests for resolvedOptions + +const languageDisplays = [ + undefined, + 'dialect', + 'standard' +]; + +languageDisplays.forEach(languageDisplay => { + const obj = new Intl.DisplayNames('en', { languageDisplay, type: 'language'}); + + assert(obj instanceof Intl.DisplayNames, `instanceof check - ${languageDisplay}`); + assert.sameValue(Object.getPrototypeOf(obj), Intl.DisplayNames.prototype, `proto check - ${languageDisplay}`); +}); diff --git a/test/intl402/DisplayNames/prototype/of/type-calendar-invalid.js b/test/intl402/DisplayNames/prototype/of/type-calendar-invalid.js new file mode 100644 index 0000000000..3ca56c39a5 --- /dev/null +++ b/test/intl402/DisplayNames/prototype/of/type-calendar-invalid.js @@ -0,0 +1,45 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-Intl.DisplayNames.prototype.of +description: Throws a RangeError for invalid `calendar` codes +features: [Intl.DisplayNames-v2] +---*/ + +var displayNames = new Intl.DisplayNames(undefined, {type: 'calendar'}); + +assert.throws(RangeError, function() { + displayNames.of('00'); +}, 'insufficient length'); + +assert.throws(RangeError, function() { + displayNames.of('000000000'); +}, 'excessive length'); + +assert.throws(RangeError, function() { + displayNames.of('-00000000'); +}, 'leading separator (dash)'); + +assert.throws(RangeError, function() { + displayNames.of('_00000000'); +}, 'leading separator (underscore)'); + +assert.throws(RangeError, function() { + displayNames.of('00000000-'); +}, 'trailing separator (dash)'); + +assert.throws(RangeError, function() { + displayNames.of('00000000_'); +}, 'trailing separator (underscore)'); + +assert.throws(RangeError, function() { + displayNames.of(' abcdef'); +}, 'leading space'); + +assert.throws(RangeError, function() { + displayNames.of('abcdef '); +}, 'trailing space'); + +assert.throws(RangeError, function() { + displayNames.of('abc def'); +}, 'interstitial space'); diff --git a/test/intl402/DisplayNames/prototype/of/type-calendar-valid.js b/test/intl402/DisplayNames/prototype/of/type-calendar-valid.js new file mode 100644 index 0000000000..7b6913fa90 --- /dev/null +++ b/test/intl402/DisplayNames/prototype/of/type-calendar-valid.js @@ -0,0 +1,32 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-Intl.DisplayNames.prototype.of +description: Returns string value for valid `calendar` codes +features: [Intl.DisplayNames-v2] +---*/ + +var displayNames = new Intl.DisplayNames(undefined, {type: 'calendar'}); + +assert.sameValue(typeof displayNames.of('01234567'), 'string', '[0-7]'); +assert.sameValue(typeof displayNames.of('899'), 'string', '[89]'); + +assert.sameValue(typeof displayNames.of('abcdefgh'), 'string', '[a-h]'); +assert.sameValue(typeof displayNames.of('ijklmnop'), 'string', '[i-p]'); +assert.sameValue(typeof displayNames.of('qrstuvwx'), 'string', '[q-x]'); +assert.sameValue(typeof displayNames.of('yzz'), 'string', '[yz]'); + +assert.sameValue(typeof displayNames.of('ABCDEFGH'), 'string', '[A-H]'); +assert.sameValue(typeof displayNames.of('IJKLMNOP'), 'string', '[I-P]'); +assert.sameValue(typeof displayNames.of('QRSTUVWX'), 'string', '[Q-X]'); +assert.sameValue(typeof displayNames.of('YZZ'), 'string', '[YZ]'); + +assert.sameValue(typeof displayNames.of('123-abc'), 'string', '2 segments, minimum length, dash'); +assert.sameValue(typeof displayNames.of('12345678-abcdefgh'), 'string', '2 segments, maximum length, dash'); +assert.sameValue(typeof displayNames.of('123-abc-ABC'), 'string', '3 segments, minimum length, dash'); +assert.sameValue(typeof displayNames.of('12345678-abcdefgh-ABCDEFGH'), 'string', '3 segments, maximum length, dash'); + +assert.sameValue(typeof displayNames.of('123_abc'), 'string', '2 segments, minimum length, underscore'); +assert.sameValue(typeof displayNames.of('12345678_abcdefgh'), 'string', '2 segments, maximum length, underscore'); +assert.sameValue(typeof displayNames.of('123_abc_ABC'), 'string', '3 segments, minimum length, underscore'); +assert.sameValue(typeof displayNames.of('12345678_abcdefgh_ABCDEFGH'), 'string', '3 segments, maximum length, underscore'); diff --git a/test/intl402/DisplayNames/prototype/of/type-datetimefield-invalid.js b/test/intl402/DisplayNames/prototype/of/type-datetimefield-invalid.js new file mode 100644 index 0000000000..706a66277f --- /dev/null +++ b/test/intl402/DisplayNames/prototype/of/type-datetimefield-invalid.js @@ -0,0 +1,37 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-Intl.DisplayNames.prototype.of +description: Throws a RangeError for invalid `dateTimeField` codes +features: [Intl.DisplayNames-v2] +---*/ + +var displayNames = new Intl.DisplayNames(undefined, {type: 'dateTimeField'}); + +assert.throws(RangeError, function() { + displayNames.of(''); +}, 'empty string'); + +assert.throws(RangeError, function() { + displayNames.of('timezoneName'); +}, 'timezoneName'); + +assert.throws(RangeError, function() { + displayNames.of('timezonename'); +}, 'timezonename'); + +assert.throws(RangeError, function() { + displayNames.of('millisecond'); +}, 'millisecond'); + +assert.throws(RangeError, function() { + displayNames.of('seconds'); +}, 'seconds'); + +assert.throws(RangeError, function() { + displayNames.of(' year'); +}, 'year (with leading space)'); + +assert.throws(RangeError, function() { + displayNames.of('year '); +}, 'year (with trailing space)'); diff --git a/test/intl402/DisplayNames/prototype/of/type-datetimefield-valid.js b/test/intl402/DisplayNames/prototype/of/type-datetimefield-valid.js new file mode 100644 index 0000000000..22325a9d9d --- /dev/null +++ b/test/intl402/DisplayNames/prototype/of/type-datetimefield-valid.js @@ -0,0 +1,22 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-Intl.DisplayNames.prototype.of +description: Returns string value for valid `dateTimeField` codes +features: [Intl.DisplayNames-v2] +---*/ + +var displayNames = new Intl.DisplayNames(undefined, {type: 'dateTimeField'}); + +assert.sameValue(typeof displayNames.of('era'), 'string', 'era'); +assert.sameValue(typeof displayNames.of('year'), 'string', 'year'); +assert.sameValue(typeof displayNames.of('quarter'), 'string', 'quarter'); +assert.sameValue(typeof displayNames.of('month'), 'string', 'month'); +assert.sameValue(typeof displayNames.of('weekOfYear'), 'string', 'weekOfYear'); +assert.sameValue(typeof displayNames.of('weekday'), 'string', 'weekday'); +assert.sameValue(typeof displayNames.of('day'), 'string', 'day'); +assert.sameValue(typeof displayNames.of('dayPeriod'), 'string', 'dayPeriod'); +assert.sameValue(typeof displayNames.of('hour'), 'string', 'hour'); +assert.sameValue(typeof displayNames.of('minute'), 'string', 'minute'); +assert.sameValue(typeof displayNames.of('second'), 'string', 'second'); +assert.sameValue(typeof displayNames.of('timeZoneName'), 'string', 'timeZoneName'); diff --git a/test/intl402/DisplayNames/prototype/resolvedOptions/option-fallback.js b/test/intl402/DisplayNames/prototype/resolvedOptions/option-fallback.js index ddb3e2acc8..b72a071f28 100644 --- a/test/intl402/DisplayNames/prototype/resolvedOptions/option-fallback.js +++ b/test/intl402/DisplayNames/prototype/resolvedOptions/option-fallback.js @@ -25,6 +25,7 @@ info: | [[Style]]: "style" [[Type]]: "type" [[Fallback]]: "fallback" + [[LanguageDisplay]]: "languageDisplay" Intl.DisplayNames ( locales , options ) diff --git a/test/intl402/DisplayNames/prototype/resolvedOptions/option-languagedisplay.js b/test/intl402/DisplayNames/prototype/resolvedOptions/option-languagedisplay.js new file mode 100644 index 0000000000..1f2b44bf15 --- /dev/null +++ b/test/intl402/DisplayNames/prototype/resolvedOptions/option-languagedisplay.js @@ -0,0 +1,68 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-Intl.DisplayNames.prototype.resolvedOptions +description: Values for the languageDisplay option +info: | + Intl.DisplayNames.prototype.resolvedOptions () + + 1. Let pr be the this value. + 2. If Type(pr) is not Object or pr does not have an [[InitializedDisplayNames]] internal slot, + throw a TypeError exception. + 3. Let options be ! ObjectCreate(%ObjectPrototype%). + 4. For each row of Table 6, except the header row, in table order, do + a. Let p be the Property value of the current row. + b. Let v be the value of pr's internal slot whose name is the Internal Slot value of the current row. + c. If v is not undefined, then + i. Perform ! CreateDataPropertyOrThrow(options, p, v). + 6. Return options. + + Table 6: Resolved Options of DisplayNames Instances + + [[Locale]]: "locale" + [[Style]]: "style" + [[Type]]: "type" + [[Fallback]]: "fallback" + [[LanguageDisplay]]: "languageDisplay" + + Intl.DisplayNames ( locales , options ) + + ... + 24. Let languageDisplay be ? GetOption(options, "languageDisplay", "string", + « "dialect", "standard" », "dialect"). + 25. If type is "language", then + a. Set displayNames.[[LanguageDisplay]] to languageDisplay. + b. Let typeFields be typeFields.[[]]. + c. Assert: typeFields is a Record (see 1.4.3). + ... + + CreateDataProperty ( O, P, V ) + + ... + 3. Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, + [[Configurable]]: true }. + ... +locale: [en-US] +features: [Intl.DisplayNames-v2] +includes: [propertyHelper.js] +---*/ + +var dn; + +dn = new Intl.DisplayNames('en-US', { type: 'language', languageDisplay: 'dialect' }); + +verifyProperty(dn.resolvedOptions(), 'languageDisplay', { + value: 'dialect', + writable: true, + enumerable: true, + configurable: true +}); + +dn = new Intl.DisplayNames('en-US', { type: 'language', languageDisplay: 'standard' }); + +verifyProperty(dn.resolvedOptions(), 'languageDisplay', { + value: 'standard', + writable: true, + enumerable: true, + configurable: true +}); diff --git a/test/intl402/DisplayNames/prototype/resolvedOptions/option-style.js b/test/intl402/DisplayNames/prototype/resolvedOptions/option-style.js index 88ca86575d..6384f66b46 100644 --- a/test/intl402/DisplayNames/prototype/resolvedOptions/option-style.js +++ b/test/intl402/DisplayNames/prototype/resolvedOptions/option-style.js @@ -25,6 +25,7 @@ info: | [[Style]]: "style" [[Type]]: "type" [[Fallback]]: "fallback" + [[LanguageDisplay]]: "languageDisplay" Intl.DisplayNames ( locales , options ) diff --git a/test/intl402/DisplayNames/prototype/resolvedOptions/option-type.js b/test/intl402/DisplayNames/prototype/resolvedOptions/option-type.js index 764c930108..f0e0258f50 100644 --- a/test/intl402/DisplayNames/prototype/resolvedOptions/option-type.js +++ b/test/intl402/DisplayNames/prototype/resolvedOptions/option-type.js @@ -25,6 +25,7 @@ info: | [[Style]]: "style" [[Type]]: "type" [[Fallback]]: "fallback" + [[LanguageDisplay]]: "languageDisplay" Intl.DisplayNames ([ locales [ , options ]])