diff options
Diffstat (limited to 'js/src/tests/test262/intl402/DateTimeFormat')
173 files changed, 6873 insertions, 0 deletions
diff --git a/js/src/tests/test262/intl402/DateTimeFormat/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/browser.js diff --git a/js/src/tests/test262/intl402/DateTimeFormat/builtin.js b/js/src/tests/test262/intl402/DateTimeFormat/builtin.js new file mode 100644 index 0000000000..abffae0582 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/builtin.js @@ -0,0 +1,21 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +es5id: 12.1_L15 +description: > + Tests that Intl.DateTimeFormat meets the requirements for + built-in objects defined by the introduction of chapter 17 of the + ECMAScript Language Specification. +author: Norbert Lindenberg +---*/ + +assert.sameValue(Object.prototype.toString.call(Intl.DateTimeFormat), "[object Function]", + "The [[Class]] internal property of a built-in function must be " + + "\"Function\"."); + +assert(Object.isExtensible(Intl.DateTimeFormat), "Built-in objects must be extensible."); + +assert.sameValue(Object.getPrototypeOf(Intl.DateTimeFormat), Function.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/casing-numbering-system-calendar-options.js b/js/src/tests/test262/intl402/DateTimeFormat/casing-numbering-system-calendar-options.js new file mode 100644 index 0000000000..0435ec2bae --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/casing-numbering-system-calendar-options.js @@ -0,0 +1,45 @@ +// Copyright 2020 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Tests that the options numberingSystem and calendar are mapped + to lower case properly. +author: Caio Lima +---*/ + +let defaultLocale = new Intl.DateTimeFormat().resolvedOptions().locale; + +let supportedNumberingSystems = ["latn", "arab"].filter(nu => + new Intl.DateTimeFormat(defaultLocale + "-u-nu-" + nu) + .resolvedOptions().numberingSystem === nu +); + +if (supportedNumberingSystems.includes("latn")) { + let dateTimeFormat = new Intl.DateTimeFormat(defaultLocale + "-u-nu-lATn"); + assert.sameValue(dateTimeFormat.resolvedOptions().numberingSystem, "latn", "Numbering system option should be in lower case"); +} + +if (supportedNumberingSystems.includes("arab")) { + let dateTimeFormat = new Intl.DateTimeFormat(defaultLocale + "-u-nu-Arab"); + assert.sameValue(dateTimeFormat.resolvedOptions().numberingSystem, "arab", "Numbering system option should be in lower case"); +} + +let supportedCalendars = ["gregory", "chinese"].filter(ca => + new Intl.DateTimeFormat(defaultLocale + "-u-ca-" + ca) + .resolvedOptions().calendar === ca +); + +if (supportedCalendars.includes("gregory")) { + let dateTimeFormat = new Intl.DateTimeFormat(defaultLocale + "-u-ca-Gregory"); + assert.sameValue(dateTimeFormat.resolvedOptions().calendar, "gregory", "Calendar option should be in lower case"); +} + +if (supportedCalendars.includes("chinese")) { + let dateTimeFormat = new Intl.DateTimeFormat(defaultLocale + "-u-ca-CHINESE"); + assert.sameValue(dateTimeFormat.resolvedOptions().calendar, "chinese", "Calendar option should be in lower case"); +} + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-calendar-numberingSystem-order.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-calendar-numberingSystem-order.js new file mode 100644 index 0000000000..d08b114c75 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-calendar-numberingSystem-order.js @@ -0,0 +1,51 @@ +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Checks the order of getting "calendar" and "numberingSystem" options in the + DateTimeFormat is between "localeMatcher" and "hour12" options. +info: | + 4. Let _matcher_ be ? GetOption(_options_, `"localeMatcher"`, `"string"`, « `"lookup"`, `"best fit"` », `"best fit"`). + ... + 6. Let _calendar_ be ? GetOption(_options_, `"calendar"`, `"string"`, *undefined*, *undefined*). + ... + 9. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, `"string"`, *undefined*, *undefined*). + ... + 12. Let _hour12_ be ? GetOption(_options_, `"hour12"`, `"boolean"`, *undefined*, *undefined*). +includes: [compareArray.js] +---*/ + +const actual = []; + +const options = { + get localeMatcher() { + actual.push("localeMatcher"); + return undefined; + }, + get calendar() { + actual.push("calendar"); + return undefined; + }, + get numberingSystem() { + actual.push("numberingSystem"); + return undefined; + }, + get hour12() { + actual.push("hour12"); + return undefined; + }, +}; + +const expected = [ + "localeMatcher", + "calendar", + "numberingSystem", + "hour12" +]; + +let df = new Intl.DateTimeFormat(undefined, options); +assert.compareArray(actual, expected); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-default-value.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-default-value.js new file mode 100644 index 0000000000..961bcfec96 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-default-value.js @@ -0,0 +1,25 @@ +// Copyright (C) 2018 Ujjwal Sharma. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Tests that the constructor for Intl.DateTimeFormat uses appropriate default + values for its arguments (locales and options). +---*/ + +const actual = new Intl.DateTimeFormat().resolvedOptions(); +const expected = new Intl.DateTimeFormat( + [], + Object.create(null) +).resolvedOptions(); + +assert.sameValue(actual.locale, expected.locale); +assert.sameValue(actual.calendar, expected.calendar); +assert.sameValue(actual.day, expected.day); +assert.sameValue(actual.month, expected.month); +assert.sameValue(actual.year, expected.year); +assert.sameValue(actual.numberingSystem, expected.numberingSystem); +assert.sameValue(actual.timeZone, expected.timeZone); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-calendar-invalid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-calendar-invalid.js new file mode 100644 index 0000000000..5ecfd4a6a1 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-calendar-invalid.js @@ -0,0 +1,42 @@ +// Copyright 2020 André Bargull; Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Checks error cases for the options argument to the DateTimeFormat constructor. +info: | + InitializeDateTimeFormat ( dateTimeFormat, locales, options ) + + ... + 7. If calendar is not undefined, then + a. If calendar does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception. +---*/ + +/* + alphanum = (ALPHA / DIGIT) ; letters and numbers + numberingSystem = (3*8alphanum) *("-" (3*8alphanum)) +*/ +const invalidCalendarOptions = [ + "", + "a", + "ab", + "abcdefghi", + "abc-abcdefghi", + "!invalid!", + "-gregory-", + "gregory-", + "gregory--", + "gregory-nu", + "gregory-nu-", + "gregory-nu-latn", + "gregoryé", + "gregory역법", +]; +for (const calendar of invalidCalendarOptions) { + assert.throws(RangeError, function() { + new Intl.DateTimeFormat('en', {calendar}); + }, `new Intl.DateTimeFormat("en", {calendar: "${calendar}"}) throws RangeError`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dateStyle-invalid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dateStyle-invalid.js new file mode 100644 index 0000000000..740bcec24f --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dateStyle-invalid.js @@ -0,0 +1,31 @@ +// Copyright 2019 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Checks error cases for the options argument to the DateTimeFormat constructor. +info: | + InitializeDateTimeFormat ( dateTimeFormat, locales, options ) + + ... + 28. Let dateStyle be ? GetOption(options, "dateStyle", "string", « "full", "long", "medium", "short" », undefined). +features: [Intl.DateTimeFormat-datetimestyle] +---*/ + + +const invalidOptions = [ + "", + "FULL", + " long", + "short ", + "narrow", + "numeric", +]; +for (const dateStyle of invalidOptions) { + assert.throws(RangeError, function() { + new Intl.DateTimeFormat("en", { dateStyle }); + }, `new Intl.DateTimeFormat("en", { dateStyle: "${dateStyle}" }) throws RangeError`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dateStyle-valid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dateStyle-valid.js new file mode 100644 index 0000000000..7de1322dcc --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dateStyle-valid.js @@ -0,0 +1,39 @@ +// Copyright 2019 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Checks handling of the options argument to the DateTimeFormat constructor. +info: | + InitializeDateTimeFormat ( dateTimeFormat, locales, options ) + + ... + 28. Let dateStyle be ? GetOption(options, "dateStyle", "string", « "full", "long", "medium", "short" », undefined). + 29. If dateStyle is not undefined, set dateTimeFormat.[[DateStyle]] to dateStyle. +features: [Intl.DateTimeFormat-datetimestyle] +---*/ + + +const validOptions = [ + [undefined, undefined], + ["full", "full"], + ["long", "long"], + ["medium", "medium"], + ["short", "short"], + [{ toString() { return "full"; } }, "full"], + [{ valueOf() { return "long"; }, toString: undefined }, "long"], +]; +for (const [dateStyle, expected] of validOptions) { + const dtf = new Intl.DateTimeFormat("en", { dateStyle }); + const options = dtf.resolvedOptions(); + assert.sameValue(options.dateStyle, expected); + const propdesc = Object.getOwnPropertyDescriptor(options, "dateStyle"); + if (expected === undefined) { + assert.sameValue(propdesc, undefined); + } else { + assert.sameValue(propdesc.value, expected); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dayPeriod-invalid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dayPeriod-invalid.js new file mode 100644 index 0000000000..abc9acb7e5 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dayPeriod-invalid.js @@ -0,0 +1,31 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Checks error cases for the options argument to the DateTimeFormat constructor. +info: | + [[DayPeriod]] `"dayPeriod"` `"narrow"`, `"short"`, `"long"` + InitializeDateTimeFormat ( dateTimeFormat, locales, options ) + + ... +features: [Intl.DateTimeFormat-dayPeriod] +---*/ + +const invalidOptions = [ + "", + "LONG", + " long", + "short ", + "full", + "numeric", +]; +for (const dayPeriod of invalidOptions) { + assert.throws(RangeError, function() { + new Intl.DateTimeFormat("en", { dayPeriod }); + }, `new Intl.DateTimeFormat("en", { dayPeriod: "${dayPeriod}" }) throws RangeError`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dayPeriod-valid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dayPeriod-valid.js new file mode 100644 index 0000000000..07da90bc5c --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-dayPeriod-valid.js @@ -0,0 +1,37 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Checks handling of the options argument to the DateTimeFormat constructor. +info: | + [[DayPeriod]] `"dayPeriod"` `"narrow"`, `"short"`, `"long"` + InitializeDateTimeFormat ( dateTimeFormat, locales, options ) + + ... +features: [Intl.DateTimeFormat-dayPeriod] +---*/ + +const validOptions = [ + [undefined, undefined], + ["long", "long"], + ["short", "short"], + ["narrow", "narrow"], + [{ toString() { return "narrow"; } }, "narrow"], + [{ valueOf() { return "long"; }, toString: undefined }, "long"], +]; +for (const [dayPeriod, expected] of validOptions) { + const dtf = new Intl.DateTimeFormat("en", { dayPeriod }); + const options = dtf.resolvedOptions(); + assert.sameValue(options.dayPeriod, expected); + const propdesc = Object.getOwnPropertyDescriptor(options, "dayPeriod"); + if (expected === undefined) { + assert.sameValue(propdesc, undefined); + } else { + assert.sameValue(propdesc.value, expected); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-fractionalSecondDigits-invalid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-fractionalSecondDigits-invalid.js new file mode 100644 index 0000000000..91d017880b --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-fractionalSecondDigits-invalid.js @@ -0,0 +1,37 @@ +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Checks error cases for the options argument to the DateTimeFormat constructor. +info: | + InitializeDateTimeFormat ( dateTimeFormat, locales, options ) + 23. Let _opt_.[[FractionalSecondDigits]] be ? GetNumberOption(_options_, `"fractionalSecondDigits"`, 0, 3, 0). + + ... +features: [Intl.DateTimeFormat-fractionalSecondDigits] +---*/ + + +const invalidOptions = [ + "LONG", + " long", + "short ", + "full", + "numeric", + -1, + 4, + "4", + "-1", + -0.00001, + 3.000001, +]; +for (const fractionalSecondDigits of invalidOptions) { + assert.throws(RangeError, function() { + new Intl.DateTimeFormat("en", { fractionalSecondDigits }); + }, + `new Intl.DateTimeFormat("en", { fractionalSecondDigits: "${fractionalSecondDigits}" }) throws RangeError`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-fractionalSecondDigits-valid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-fractionalSecondDigits-valid.js new file mode 100644 index 0000000000..be82eca19b --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-fractionalSecondDigits-valid.js @@ -0,0 +1,40 @@ +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Checks handling of the options argument to the DateTimeFormat constructor. +info: | + InitializeDateTimeFormat ( dateTimeFormat, locales, options ) + 23. Let _opt_.[[FractionalSecondDigits]] be ? GetNumberOption(_options_, `"fractionalSecondDigits"`, 0, 3, 0). +features: [Intl.DateTimeFormat-fractionalSecondDigits] +---*/ + + +const validOptions = [ + [undefined, undefined], + [1, 1], + ["1", 1], + [2, 2], + ["2", 2], + [3, 3], + ["3", 3], + [2.9, 2], + ["2.9", 2], + [1.00001, 1], + [{ toString() { return "3"; } }, 3], +]; +for (const [fractionalSecondDigits, expected] of validOptions) { + const dtf = new Intl.DateTimeFormat("en", { fractionalSecondDigits }); + const options = dtf.resolvedOptions(); + assert.sameValue(options.fractionalSecondDigits, expected); + const propdesc = Object.getOwnPropertyDescriptor(options, "fractionalSecondDigits"); + if (expected === undefined) { + assert.sameValue(propdesc, undefined); + } else { + assert.sameValue(propdesc.value, expected); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-numberingSystem-invalid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-numberingSystem-invalid.js new file mode 100644 index 0000000000..c77053a209 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-numberingSystem-invalid.js @@ -0,0 +1,42 @@ +// Copyright 2020 André Bargull; Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Checks error cases for the options argument to the DateTimeFormat constructor. +info: | + InitializeDateTimeFormat ( dateTimeFormat, locales, options ) + + ... + 10. If numberingSystem is not undefined, then + a. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception. +---*/ + +/* + alphanum = (ALPHA / DIGIT) ; letters and numbers + numberingSystem = (3*8alphanum) *("-" (3*8alphanum)) +*/ +const invalidNumberingSystemOptions = [ + "", + "a", + "ab", + "abcdefghi", + "abc-abcdefghi", + "!invalid!", + "-latn-", + "latn-", + "latn--", + "latn-ca", + "latn-ca-", + "latn-ca-gregory", + "latné", + "latn编号", +]; +for (const numberingSystem of invalidNumberingSystemOptions) { + assert.throws(RangeError, function() { + new Intl.DateTimeFormat('en', {numberingSystem}); + }, `new Intl.DateTimeFormat("en", {numberingSystem: "${numberingSystem}"}) throws RangeError`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-dayPeriod.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-dayPeriod.js new file mode 100644 index 0000000000..4620f1964a --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-dayPeriod.js @@ -0,0 +1,51 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet +// Copyright 2019 Googe Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks the order of getting options of 'dayPeriod' for the DateTimeFormat constructor. +info: | + ToDateTimeOptions ( options, required, defaults ) + 4. If required is "date" or "any", then + a. For each of the property names "weekday", "year", "month", "day", "dayPeriod" do + 5. If required is "time" or "any", then + a. For each of the property names "hour", "minute", "second", do +includes: [compareArray.js] +features: [Intl.DateTimeFormat-dayPeriod] + +---*/ + +// Just need to ensure dayPeriod are get between day and hour. +const expected = [ + // ToDateTimeOptions step 4. + "day", "dayPeriod", + // ToDateTimeOptions step 5. + "hour", + // InitializeDateTimeFormat step 22. + "day", + "dayPeriod", + "hour" +]; + +const actual = []; + +const options = { + get day() { + actual.push("day"); + return "numeric"; + }, + get dayPeriod() { + actual.push("dayPeriod"); + return "long"; + }, + get hour() { + actual.push("hour"); + return "numeric"; + }, +}; + +new Intl.DateTimeFormat("en", options); +assert.compareArray(actual, expected); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-fractionalSecondDigits.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-fractionalSecondDigits.js new file mode 100644 index 0000000000..1daaba4107 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-fractionalSecondDigits.js @@ -0,0 +1,69 @@ +// Copyright 2019 Googe Inc. All rights reserved. +// Copyright 2020 Apple Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks the order of getting options of 'fractionalSecondDigits' for the DateTimeFormat constructor. +info: | + ToDateTimeOptions ( options, required, defaults ) + 5. If required is "time" or "any", then + a. For each of the property names "hour", "minute", "second", "fractionalSecondDigits", do + + InitializeDateTimeFormat ( dateTimeFormat, locales, options ) + 2. Let options be ? ToDateTimeOptions(options, "any", "date"). + 4. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit"). + 22. For each row of Table 5, except the header row, do + a. Let value be ? GetOption(options, prop, "string", « the strings given in the Values column of the row », undefined). + 23. Let _opt_.[[FractionalSecondDigits]] be ? GetNumberOption(_options_, `"fractionalSecondDigits"`, 0, 3, 0). + 26. Let matcher be ? GetOption(options, "formatMatcher", "string", « "basic", "best fit" », "best fit"). +includes: [compareArray.js] +features: [Intl.DateTimeFormat-fractionalSecondDigits] +---*/ + +// Just need to ensure fractionalSecondDigits are get +// between second and localeMatcher the first time and +// between timeZoneName and formatMatcher the second time. +const expected = [ + // InitializeDateTimeFormat step 2. + // ToDateTimeOptions step 5. + "second", "fractionalSecondDigits", + // InitializeDateTimeFormat step 4. + "localeMatcher", + // InitializeDateTimeFormat step 22. + "second", + "fractionalSecondDigits", + "timeZoneName", + // InitializeDateTimeFormat step 26. + "formatMatcher", +]; + +const actual = []; + +const options = { + get second() { + actual.push("second"); + return "numeric"; + }, + get fractionalSecondDigits() { + actual.push("fractionalSecondDigits"); + return undefined; + }, + get localeMatcher() { + actual.push("localeMatcher"); + return undefined; + }, + get timeZoneName() { + actual.push("timeZoneName"); + return undefined; + }, + get formatMatcher() { + actual.push("formatMatcher"); + return undefined; + }, +}; + +new Intl.DateTimeFormat("en", options); +assert.compareArray(actual, expected); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-timedate-style.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-timedate-style.js new file mode 100644 index 0000000000..c074860b8f --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order-timedate-style.js @@ -0,0 +1,136 @@ +// Copyright 2018 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks the order of getting options for the DateTimeFormat constructor. +includes: [compareArray.js] +features: [Intl.DateTimeFormat-datetimestyle] +---*/ + +// To be merged into constructor-options-order.js when the feature is removed. + +const expected = [ + // ToDateTimeOptions step 4. + "weekday", "year", "month", "day", + // ToDateTimeOptions step 5. + "hour", "minute", "second", + // ToDateTimeOptions step 6. + "dateStyle", + // ToDateTimeOptions step 7. + "timeStyle", + + // InitializeDateTimeFormat step 4. + "localeMatcher", + // InitializeDateTimeFormat step 6. + "hour12", + // InitializeDateTimeFormat step 7. + "hourCycle", + // InitializeDateTimeFormat step 23. + "timeZone", + // InitializeDateTimeFormat step 28. + "weekday", + "era", + "year", + "month", + "day", + "hour", + "minute", + "second", + "timeZoneName", + "formatMatcher", + // InitializeDateTimeFormat step 32. + "dateStyle", + // InitializeDateTimeFormat step 33. + "timeStyle", +]; + +const actual = []; + +const options = { + get dateStyle() { + actual.push("dateStyle"); + return undefined; + }, + + get day() { + actual.push("day"); + return "numeric"; + }, + + get era() { + actual.push("era"); + return "long"; + }, + + get formatMatcher() { + actual.push("formatMatcher"); + return "best fit"; + }, + + get hour() { + actual.push("hour"); + return "numeric"; + }, + + get hour12() { + actual.push("hour12"); + return true; + }, + + get hourCycle() { + actual.push("hourCycle"); + return "h24"; + }, + + get localeMatcher() { + actual.push("localeMatcher"); + return "best fit"; + }, + + get minute() { + actual.push("minute"); + return "numeric"; + }, + + get month() { + actual.push("month"); + return "numeric"; + }, + + get second() { + actual.push("second"); + return "numeric"; + }, + + get timeStyle() { + actual.push("timeStyle"); + return undefined; + }, + + get timeZone() { + actual.push("timeZone"); + return "UTC"; + }, + + get timeZoneName() { + actual.push("timeZoneName"); + return "long"; + }, + + get weekday() { + actual.push("weekday"); + return "long"; + }, + + get year() { + actual.push("year"); + return "numeric"; + }, +}; + +new Intl.DateTimeFormat("en", options); + +assert.compareArray(actual, expected); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order.js new file mode 100644 index 0000000000..25dade65e0 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-order.js @@ -0,0 +1,116 @@ +// Copyright 2018 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks the order of getting options for the DateTimeFormat constructor. +includes: [compareArray.js] +---*/ + +const expected = [ + // ToDateTimeOptions step 4. + "weekday", "year", "month", "day", + // ToDateTimeOptions step 5. + "hour", "minute", "second", + + // InitializeDateTimeFormat step 4. + "localeMatcher", + // InitializeDateTimeFormat step 6. + "hour12", + // InitializeDateTimeFormat step 7. + "hourCycle", + // InitializeDateTimeFormat step 17. + "timeZone", + // InitializeDateTimeFormat step 22. + "weekday", + "era", + "year", + "month", + "day", + "hour", + "minute", + "second", + "timeZoneName", + // InitializeDateTimeFormat step 25. + "formatMatcher", +]; + +const actual = []; + +const options = { + get day() { + actual.push("day"); + return "numeric"; + }, + + get era() { + actual.push("era"); + return "long"; + }, + + get formatMatcher() { + actual.push("formatMatcher"); + return "best fit"; + }, + + get hour() { + actual.push("hour"); + return "numeric"; + }, + + get hour12() { + actual.push("hour12"); + return true; + }, + + get hourCycle() { + actual.push("hourCycle"); + return "h24"; + }, + + get localeMatcher() { + actual.push("localeMatcher"); + return "best fit"; + }, + + get minute() { + actual.push("minute"); + return "numeric"; + }, + + get month() { + actual.push("month"); + return "numeric"; + }, + + get second() { + actual.push("second"); + return "numeric"; + }, + + get timeZone() { + actual.push("timeZone"); + return "UTC"; + }, + + get timeZoneName() { + actual.push("timeZoneName"); + return "long"; + }, + + get weekday() { + actual.push("weekday"); + return "long"; + }, + + get year() { + actual.push("year"); + return "numeric"; + }, +}; + +new Intl.DateTimeFormat("en", options); + +assert.compareArray(actual, expected); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-dayPeriod.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-dayPeriod.js new file mode 100644 index 0000000000..099438ae65 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-dayPeriod.js @@ -0,0 +1,27 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks the propagation of exceptions from the options for the DateTimeFormat constructor. +features: [Intl.DateTimeFormat-dayPeriod] +---*/ + +function CustomError() {} + +const options = [ + "dayPeriod", +]; + +for (const option of options) { + assert.throws(CustomError, () => { + new Intl.DateTimeFormat("en", { + get [option]() { + throw new CustomError(); + } + }); + }, `Exception from ${option} getter should be propagated`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-fractionalSecondDigits.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-fractionalSecondDigits.js new file mode 100644 index 0000000000..f438e8df97 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-fractionalSecondDigits.js @@ -0,0 +1,26 @@ +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks the propagation of exceptions from the options for the DateTimeFormat constructor. +features: [Intl.DateTimeFormat-fractionalSecondDigits] +---*/ + +function CustomError() {} + +const options = [ + "fractionalSecondDigits", +]; + +for (const option of options) { + assert.throws(CustomError, () => { + new Intl.DateTimeFormat("en", { + get [option]() { + throw new CustomError(); + } + }); + }, `Exception from ${option} getter should be propagated`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-timedate-style.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-timedate-style.js new file mode 100644 index 0000000000..448acfa175 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters-timedate-style.js @@ -0,0 +1,31 @@ +// Copyright 2018 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks the propagation of exceptions from the options for the DateTimeFormat constructor. +features: [Intl.DateTimeFormat-datetimestyle] +---*/ + +// To be merged into constructor-options-throwing-getters.js when the feature is removed. + +function CustomError() {} + +const options = [ + // InitializeDateTimeFormat step 28 + "dateStyle", + // InitializeDateTimeFormat step 30 + "timeStyle", +]; + +for (const option of options) { + assert.throws(CustomError, () => { + new Intl.DateTimeFormat("en", { + get [option]() { + throw new CustomError(); + } + }); + }, `Exception from ${option} getter should be propagated`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters.js new file mode 100644 index 0000000000..c7faeabb74 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-throwing-getters.js @@ -0,0 +1,33 @@ +// Copyright 2018 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks the propagation of exceptions from the options for the DateTimeFormat constructor. +---*/ + +function CustomError() {} + +const options = [ + "weekday", "year", "month", "day", + "hour", "minute", "second", + "localeMatcher", + "hour12", + "hourCycle", + "timeZone", + "era", + "timeZoneName", + "formatMatcher", +]; + +for (const option of options) { + assert.throws(CustomError, () => { + new Intl.DateTimeFormat("en", { + get [option]() { + throw new CustomError(); + } + }); + }, `Exception from ${option} getter should be propagated`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-timeStyle-invalid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-timeStyle-invalid.js new file mode 100644 index 0000000000..6979587966 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-timeStyle-invalid.js @@ -0,0 +1,31 @@ +// Copyright 2019 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Checks error cases for the options argument to the DateTimeFormat constructor. +info: | + InitializeDateTimeFormat ( dateTimeFormat, locales, options ) + + ... + 30. Let timeStyle be ? GetOption(options, "timeStyle", "string", « "full", "long", "medium", "short" », undefined). +features: [Intl.DateTimeFormat-datetimestyle] +---*/ + + +const invalidOptions = [ + "", + "FULL", + " long", + "short ", + "narrow", + "numeric", +]; +for (const timeStyle of invalidOptions) { + assert.throws(RangeError, function() { + new Intl.DateTimeFormat("en", { timeStyle }); + }, `new Intl.DateTimeFormat("en", { timeStyle: "${timeStyle}" }) throws RangeError`); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-timeStyle-valid.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-timeStyle-valid.js new file mode 100644 index 0000000000..cc8665fe44 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-timeStyle-valid.js @@ -0,0 +1,38 @@ +// Copyright 2019 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Checks handling of the options argument to the DateTimeFormat constructor. +info: | + InitializeDateTimeFormat ( dateTimeFormat, locales, options ) + + ... + 30. Let timeStyle be ? GetOption(options, "timeStyle", "string", « "full", "long", "medium", "short" », undefined). + 31. If timeStyle is not undefined, set dateTimeFormat.[[TimeStyle]] to timeStyle. +features: [Intl.DateTimeFormat-datetimestyle] +---*/ + +const validOptions = [ + [undefined, undefined], + ["full", "full"], + ["long", "long"], + ["medium", "medium"], + ["short", "short"], + [{ toString() { return "full"; } }, "full"], + [{ valueOf() { return "long"; }, toString: undefined }, "long"], +]; +for (const [timeStyle, expected] of validOptions) { + const dtf = new Intl.DateTimeFormat("en", { timeStyle }); + const options = dtf.resolvedOptions(); + assert.sameValue(options.timeStyle, expected); + const propdesc = Object.getOwnPropertyDescriptor(options, "timeStyle"); + if (expected === undefined) { + assert.sameValue(propdesc, undefined); + } else { + assert.sameValue(propdesc.value, expected); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-toobject.js b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-toobject.js new file mode 100644 index 0000000000..bde3e584d2 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/constructor-options-toobject.js @@ -0,0 +1,44 @@ +// Copyright (C) 2018 Ujjwal Sharma. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Tests that Intl.DateTimeFormat contructor converts the options argument + to an object using `ToObject` (7.1.13). +info: | + 12.1.2 ToDateTimeOptions + + 1. If options is undefined, let options be null; otherwise let options be ? + ToObject(options). +---*/ + +const toObjectResults = [ + [true, new Boolean(true)], + [42, new Number(42)], + ['foo', new String('foo')], + [{}, {}], + [Symbol(), Object(Symbol())] +]; + +// Test if ToObject is used to convert primitives to Objects. +toObjectResults.forEach(pair => { + const [value, result] = pair; + + const actual = new Intl.DateTimeFormat(['en-US'], value).resolvedOptions(); + const expected = new Intl.DateTimeFormat(['en-US'], result).resolvedOptions(); + + assert.sameValue(actual.locale, expected.locale); + assert.sameValue(actual.calendar, expected.calendar); + assert.sameValue(actual.day, expected.day); + assert.sameValue(actual.month, expected.month); + assert.sameValue(actual.year, expected.year); + assert.sameValue(actual.numberingSystem, expected.numberingSystem); + assert.sameValue(actual.timeZone, expected.timeZone); +}); + +// ToObject throws a TypeError for undefined and null, but it's not called +// when options is undefined. +assert.throws(TypeError, () => new Intl.DateTimeFormat(['en-US'], null)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/date-time-options.js b/js/src/tests/test262/intl402/DateTimeFormat/date-time-options.js new file mode 100644 index 0000000000..bfe57ade97 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/date-time-options.js @@ -0,0 +1,106 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 12.1.1_TDTO +description: > + Tests that the set of options for the date and time components is + processed correctly. +author: Norbert Lindenberg +includes: [testIntl.js] +---*/ + +var locales = [[], ["zh-Hans-CN"], ["hi-IN"], ["en-US"], ["id-ID"]]; +var dates = [new Date(), new Date(0), new Date(Date.parse("1989-11-09T17:57:00Z"))]; + +function testWithDateTimeFormat(options, expected) { + locales.forEach(function (locales) { + var format = new Intl.DateTimeFormat(locales, options); + var resolvedOptions = format.resolvedOptions(); + getDateTimeComponents().forEach(function (component) { + if (resolvedOptions.hasOwnProperty(component)) { + assert(expected.hasOwnProperty(component), + "Unrequested component " + component + + " added to expected subset " + JSON.stringify(expected) + + "; locales " + locales + ", options " + + (options ? JSON.stringify(options) : options) + "."); + } else { + assert.sameValue(expected.hasOwnProperty(component), false, + "Missing component " + component + + " from expected subset " + JSON.stringify(expected) + + "; locales " + locales + ", options " + + (options ? JSON.stringify(options) : options) + "."); + } + }); + }); +} + +function testWithToLocale(f, options, expected) { + // expected can be either one subset or an array of possible subsets + if (expected.length === undefined) { + expected = [expected]; + } + locales.forEach(function (locales) { + dates.forEach(function (date) { + var formatted = Date.prototype[f].call(date, locales, options); + var expectedStrings = []; + expected.forEach(function (expected) { + var referenceFormat = new Intl.DateTimeFormat(locales, expected); + expectedStrings.push(referenceFormat.format(date)); + }); + assert.notSameValue(expectedStrings.indexOf(formatted), -1, + "Function " + f + " did not return expected string for locales " + + locales + ", options " + (options? JSON.stringify(options) : options) + + "; expected " + + (expectedStrings.length === 1 ? expectedStrings[0] : "one of " + expectedStrings) + + ", got " + formatted + "."); + }); + }); +} + +// any/date: steps 5a, 6a, 7a +testWithDateTimeFormat(undefined, {year: "numeric", month: "numeric", day: "numeric"}); + +// any/date: steps 5a, 6a +testWithDateTimeFormat({year: "numeric", month: "numeric"}, {year: "numeric", month: "numeric"}); + +// any/date: steps 5a, 6a +testWithDateTimeFormat({hour: "numeric", minute: "numeric"}, {hour: "numeric", minute: "numeric"}); + +// any/all: steps 5a, 6a, 7a, 8a +testWithToLocale("toLocaleString", undefined, [ + // the first one is not guaranteed to be supported; the second one is + {year: "numeric", month: "numeric", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric"}, + {weekday: "short", year: "numeric", month: "numeric", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric"} +]); + +// any/all: steps 5a, 6a +testWithToLocale("toLocaleString", {year: "numeric", month: "numeric"}, {year: "numeric", month: "numeric"}); + +// any/all: steps 5a, 6a +testWithToLocale("toLocaleString", {hour: "numeric", minute: "numeric"}, {hour: "numeric", minute: "numeric"}); + +// date/date: steps 5a, 7a +testWithToLocale("toLocaleDateString", undefined, {year: "numeric", month: "numeric", day: "numeric"}); + +// date/date: steps 5a +testWithToLocale("toLocaleDateString", {year: "numeric", month: "numeric"}, {year: "numeric", month: "numeric"}); + +// date/date: steps 5a, 7a +testWithToLocale("toLocaleDateString", {hour: "numeric", minute: "numeric", second: "numeric"}, [ + // the first one is not guaranteed to be supported; the second one is + {year: "numeric", month: "numeric", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric"}, + {weekday: "short", year: "numeric", month: "numeric", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric"} +]); + +// time/time: steps 6a, 8a +testWithToLocale("toLocaleTimeString", undefined, {hour: "numeric", minute: "numeric", second: "numeric"}); + +// time/time: steps 6a, 8a +testWithToLocale("toLocaleTimeString", {weekday: "short", year: "numeric", month: "numeric", day: "numeric"}, + {weekday: "short", year: "numeric", month: "numeric", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric"}); + +// time/time: steps 6a +testWithToLocale("toLocaleTimeString", {hour: "numeric", minute: "numeric"}, {hour: "numeric", minute: "numeric"}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/default-options-object-prototype.js b/js/src/tests/test262/intl402/DateTimeFormat/default-options-object-prototype.js new file mode 100644 index 0000000000..854e5ff3f1 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/default-options-object-prototype.js @@ -0,0 +1,22 @@ +// Copyright (C) 2017 Daniel Ehrenberg. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-todatetimeoptions +description: > + Monkey-patching Object.prototype does not change the default + options for DateTimeFormat as a null prototype is used. +info: | + ToDateTimeOptions ( options, required, defaults ) + + 1. If options is undefined, let options be null; otherwise let options be ? ToObject(options). + 1. Let options be ObjectCreate(options). +---*/ + +let defaultYear = new Intl.DateTimeFormat("en").resolvedOptions().year; + +Object.prototype.year = "2-digit"; +let formatter = new Intl.DateTimeFormat("en"); +assert.sameValue(formatter.resolvedOptions().year, defaultYear); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/ignore-invalid-unicode-ext-values.js b/js/src/tests/test262/intl402/DateTimeFormat/ignore-invalid-unicode-ext-values.js new file mode 100644 index 0000000000..34c9829741 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/ignore-invalid-unicode-ext-values.js @@ -0,0 +1,39 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +es5id: 12.2.3_b +description: > + Tests that Intl.DateTimeFormat does not accept Unicode locale + extension keys and values that are not allowed. +author: Norbert Lindenberg +---*/ + +var locales = ["ja-JP", "zh-Hans-CN", "zh-Hant-TW"]; +var input = new Date(Date.parse("1989-11-09T17:57:00Z")); + +locales.forEach(function (locale) { + var defaultDateTimeFormat = new Intl.DateTimeFormat([locale]); + var defaultOptions = defaultDateTimeFormat.resolvedOptions(); + var defaultOptionsJSON = JSON.stringify(defaultOptions); + var defaultLocale = defaultOptions.locale; + var defaultFormatted = defaultDateTimeFormat.format(input); + + var keyValues = { + "cu": ["USD", "EUR", "JPY", "CNY", "TWD", "invalid"], // DateTimeFormat internally uses NumberFormat + "nu": ["native", "traditio", "finance", "invalid"], + "tz": ["usnavajo", "utcw01", "aumel", "uslax", "usnyc", "deber", "invalid"] + }; + + Object.getOwnPropertyNames(keyValues).forEach(function (key) { + keyValues[key].forEach(function (value) { + var dateTimeFormat = new Intl.DateTimeFormat([locale + "-u-" + key + "-" + value]); + var options = dateTimeFormat.resolvedOptions(); + assert.sameValue(options.locale, defaultLocale, "Locale " + options.locale + " is affected by key " + key + "; value " + value + "."); + assert.sameValue(JSON.stringify(options), defaultOptionsJSON, "Resolved options " + JSON.stringify(options) + " are affected by key " + key + "; value " + value + "."); + assert.sameValue(dateTimeFormat.format(input), defaultFormatted, "Formatted value " + dateTimeFormat.format(input) + " is affected by key " + key + "; value " + value + "."); + }); + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/instance-proto-and-extensible.js b/js/src/tests/test262/intl402/DateTimeFormat/instance-proto-and-extensible.js new file mode 100644 index 0000000000..34e6873529 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/instance-proto-and-extensible.js @@ -0,0 +1,19 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 12.1.3 +description: > + Tests that objects constructed by Intl.DateTimeFormat have the + specified internal properties. +author: Norbert Lindenberg +---*/ + +var obj = new Intl.DateTimeFormat(); + +var actualPrototype = Object.getPrototypeOf(obj); +assert.sameValue(actualPrototype, Intl.DateTimeFormat.prototype, "Prototype of object constructed by Intl.DateTimeFormat isn't Intl.DateTimeFormat.prototype."); + +assert(Object.isExtensible(obj), "Object constructed by Intl.DateTimeFormat must be extensible."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/intl-legacy-constructed-symbol-on-unwrap.js b/js/src/tests/test262/intl402/DateTimeFormat/intl-legacy-constructed-symbol-on-unwrap.js new file mode 100644 index 0000000000..61b9452d9a --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/intl-legacy-constructed-symbol-on-unwrap.js @@ -0,0 +1,34 @@ +// Copyright 2020 Apple Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-unwrapdatetimeformat +description: > + Tests that [[FallbackSymbol]]'s [[Description]] is "IntlLegacyConstructedSymbol" if normative optional is implemented. +author: Yusuke Suzuki +features: [intl-normative-optional] +---*/ + +let object = new Intl.DateTimeFormat(); +let newObject = Intl.DateTimeFormat.call(object); +let symbol = null; +let error = null; +try { + let proxy = new Proxy(newObject, { + get(target, property) { + symbol = property; + return target[property]; + } + }); + Intl.DateTimeFormat.prototype.resolvedOptions.call(proxy); +} catch (e) { + // If normative optional is not implemented, an error will be thrown. + error = e; + assert(error instanceof TypeError); +} +if (error === null) { + assert.sameValue(typeof symbol, "symbol"); + assert.sameValue(symbol.description, "IntlLegacyConstructedSymbol"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/intl-legacy-constructed-symbol.js b/js/src/tests/test262/intl402/DateTimeFormat/intl-legacy-constructed-symbol.js new file mode 100644 index 0000000000..6ca345b44e --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/intl-legacy-constructed-symbol.js @@ -0,0 +1,20 @@ +// Copyright 2020 Apple Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat +description: > + Tests that [[FallbackSymbol]]'s [[Description]] is "IntlLegacyConstructedSymbol" if normative optional is implemented. +author: Yusuke Suzuki +features: [intl-normative-optional] +---*/ + +let object = new Intl.DateTimeFormat(); +let newObject = Intl.DateTimeFormat.call(object); +let symbols = Object.getOwnPropertySymbols(newObject); +if (symbols.length !== 0) { + assert.sameValue(symbols.length, 1); + assert.sameValue(symbols[0].description, "IntlLegacyConstructedSymbol"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/legacy-regexp-statics-not-modified.js b/js/src/tests/test262/intl402/DateTimeFormat/legacy-regexp-statics-not-modified.js new file mode 100644 index 0000000000..6d44737ef4 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/legacy-regexp-statics-not-modified.js @@ -0,0 +1,21 @@ +// Copyright 2013 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 12.1.1_a +description: > + Tests that constructing a DateTimeFormat doesn't create or modify + unwanted properties on the RegExp constructor. +author: Norbert Lindenberg +includes: [testIntl.js] +---*/ + +testForUnwantedRegExpChanges(function () { + new Intl.DateTimeFormat("de-DE-u-ca-gregory"); +}); + +testForUnwantedRegExpChanges(function () { + new Intl.DateTimeFormat("de-DE-u-ca-gregory", {timeZone: "UTC"}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/length.js b/js/src/tests/test262/intl402/DateTimeFormat/length.js new file mode 100644 index 0000000000..39331d3787 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/length.js @@ -0,0 +1,33 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat +description: > + Intl.DateTimeFormat.length is 0. +info: | + Intl.DateTimeFormat ( [ locales [ , options ] ] ) + + 17 ECMAScript Standard Built-in Objects: + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + Unless otherwise specified, the length property of a built-in function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. + +includes: [propertyHelper.js] +---*/ + +assert.sameValue(Intl.DateTimeFormat.length, 0); + +verifyNotEnumerable(Intl.DateTimeFormat, "length"); +verifyNotWritable(Intl.DateTimeFormat, "length"); +verifyConfigurable(Intl.DateTimeFormat, "length"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/name.js b/js/src/tests/test262/intl402/DateTimeFormat/name.js new file mode 100644 index 0000000000..434fd31ef3 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/name.js @@ -0,0 +1,28 @@ +// Copyright (C) 2016 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DateTimeFormat +description: > + Intl.DateTimeFormat.name is "DateTimeFormat". +info: | + 12.2.1 Intl.DateTimeFormat ([ locales [ , options ]]) + + 17 ECMAScript Standard Built-in Objects: + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +---*/ + +assert.sameValue(Intl.DateTimeFormat.name, "DateTimeFormat"); + +verifyNotEnumerable(Intl.DateTimeFormat, "name"); +verifyNotWritable(Intl.DateTimeFormat, "name"); +verifyConfigurable(Intl.DateTimeFormat, "name"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/numbering-system-calendar-options.js b/js/src/tests/test262/intl402/DateTimeFormat/numbering-system-calendar-options.js new file mode 100644 index 0000000000..b7cd7a3241 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/numbering-system-calendar-options.js @@ -0,0 +1,69 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Tests that the options numberingSystem and calendar can be set through + either the locale or the options. +author: Norbert Lindenberg, Daniel Ehrenberg +---*/ + +let defaultLocale = new Intl.DateTimeFormat().resolvedOptions().locale; + +let supportedNumberingSystems = ["latn", "arab"].filter(nu => + new Intl.DateTimeFormat(defaultLocale + "-u-nu-" + nu) + .resolvedOptions().numberingSystem === nu +); + +let supportedCalendars = ["gregory", "chinese"].filter(ca => + new Intl.DateTimeFormat(defaultLocale + "-u-ca-" + ca) + .resolvedOptions().calendar === ca +); + +let options = [ + {key: "nu", property: "numberingSystem", type: "string", values: supportedNumberingSystems}, + {key: "ca", property: "calendar", type: "string", values: supportedCalendars} +]; + +options.forEach(function (option) { + let dateTimeFormat, opt, result; + + // find out which values are supported for a property in the default locale + let supportedValues = []; + option.values.forEach(function (value) { + opt = {}; + opt[option.property] = value; + dateTimeFormat = new Intl.DateTimeFormat([defaultLocale], opt); + result = dateTimeFormat.resolvedOptions()[option.property]; + if (result !== undefined && supportedValues.indexOf(result) === -1) { + supportedValues.push(result); + } + }); + + // verify that the supported values can also be set through the locale + supportedValues.forEach(function (value) { + dateTimeFormat = new Intl.DateTimeFormat([defaultLocale + "-u-" + option.key + "-" + value]); + result = dateTimeFormat.resolvedOptions()[option.property]; + assert.sameValue(result, value, "Property " + option.property + " couldn't be set through locale extension key " + option.key + "."); + }); + + // verify that the options setting overrides the locale setting + supportedValues.forEach(function (value) { + let otherValue; + option.values.forEach(function (possibleValue) { + if (possibleValue !== value) { + otherValue = possibleValue; + } + }); + if (otherValue !== undefined) { + opt = {}; + opt[option.property] = value; + dateTimeFormat = new Intl.DateTimeFormat([defaultLocale + "-u-" + option.key + "-" + otherValue], opt); + result = dateTimeFormat.resolvedOptions()[option.property]; + assert.sameValue(result, value, "Options value for property " + option.property + " doesn't override locale extension key " + option.key + "."); + } + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prop-desc.js b/js/src/tests/test262/intl402/DateTimeFormat/prop-desc.js new file mode 100644 index 0000000000..7b236b882f --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prop-desc.js @@ -0,0 +1,31 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat-intro +description: > + "DateTimeFormat" property of Intl. +info: | + Intl.DateTimeFormat (...) + + 7 Requirements for Standard Built-in ECMAScript Objects + + Unless specified otherwise in this document, the objects, functions, and constructors + described in this standard are subject to the generic requirements and restrictions + specified for standard built-in ECMAScript objects in the ECMAScript 2018 Language + Specification, 9th edition, clause 17, or successor. + + 17 ECMAScript Standard Built-in Objects: + + Every other data property described in clauses 18 through 26 and in Annex B.2 has the + attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } + unless otherwise specified. + +includes: [propertyHelper.js] +---*/ + +verifyNotEnumerable(Intl, "DateTimeFormat"); +verifyWritable(Intl, "DateTimeFormat"); +verifyConfigurable(Intl, "DateTimeFormat"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/proto-from-ctor-realm.js b/js/src/tests/test262/intl402/DateTimeFormat/proto-from-ctor-realm.js new file mode 100644 index 0000000000..118fadf545 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/proto-from-ctor-realm.js @@ -0,0 +1,60 @@ +// Copyright (C) 2019 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat +description: Default [[Prototype]] value derived from realm of the NewTarget. +info: | + Intl.DateTimeFormat ( [ locales [ , options ] ] ) + + 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget. + 2. Let dateTimeFormat be ? OrdinaryCreateFromConstructor(newTarget, "%DateTimeFormatPrototype%", « ... »). + ... + 6. Return dateTimeFormat. + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + ... + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return ObjectCreate(proto, internalSlotsList). + + GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ) + + ... + 3. Let proto be ? Get(constructor, 'prototype'). + 4. If Type(proto) is not Object, then + a. Let realm be ? GetFunctionRealm(constructor). + b. Set proto to realm's intrinsic object named intrinsicDefaultProto. + 5. Return proto. +features: [cross-realm, Reflect, Symbol] +---*/ + +var other = $262.createRealm().global; +var newTarget = new other.Function(); +var dtf; + +newTarget.prototype = undefined; +dtf = Reflect.construct(Intl.DateTimeFormat, [], newTarget); +assert.sameValue(Object.getPrototypeOf(dtf), other.Intl.DateTimeFormat.prototype, 'newTarget.prototype is undefined'); + +newTarget.prototype = null; +dtf = Reflect.construct(Intl.DateTimeFormat, [], newTarget); +assert.sameValue(Object.getPrototypeOf(dtf), other.Intl.DateTimeFormat.prototype, 'newTarget.prototype is null'); + +newTarget.prototype = false; +dtf = Reflect.construct(Intl.DateTimeFormat, [], newTarget); +assert.sameValue(Object.getPrototypeOf(dtf), other.Intl.DateTimeFormat.prototype, 'newTarget.prototype is a Boolean'); + +newTarget.prototype = 'str'; +dtf = Reflect.construct(Intl.DateTimeFormat, [], newTarget); +assert.sameValue(Object.getPrototypeOf(dtf), other.Intl.DateTimeFormat.prototype, 'newTarget.prototype is a String'); + +newTarget.prototype = Symbol(); +dtf = Reflect.construct(Intl.DateTimeFormat, [], newTarget); +assert.sameValue(Object.getPrototypeOf(dtf), other.Intl.DateTimeFormat.prototype, 'newTarget.prototype is a Symbol'); + +newTarget.prototype = 1; +dtf = Reflect.construct(Intl.DateTimeFormat, [], newTarget); +assert.sameValue(Object.getPrototypeOf(dtf), other.Intl.DateTimeFormat.prototype, 'newTarget.prototype is a Number'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/browser.js diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/builtin.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/builtin.js new file mode 100644 index 0000000000..dd849faaef --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/builtin.js @@ -0,0 +1,18 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +es5id: 12.3_L15 +description: > + Tests that Intl.DateTimeFormat.prototype meets the requirements + for built-in objects defined by the introduction of chapter 17 of + the ECMAScript Language Specification. +author: Norbert Lindenberg +---*/ + +assert(Object.isExtensible(Intl.DateTimeFormat.prototype), "Built-in objects must be extensible."); + +assert.sameValue(Object.getPrototypeOf(Intl.DateTimeFormat.prototype), Object.prototype, + "Built-in prototype objects must have Object.prototype as their prototype."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/browser.js diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/prop-desc.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/prop-desc.js new file mode 100644 index 0000000000..13826e9fa1 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/prop-desc.js @@ -0,0 +1,31 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype.constructor +description: > + "constructor" property of Intl.DateTimeFormat.prototype. +info: | + Intl.DateTimeFormat.prototype.constructor + + 7 Requirements for Standard Built-in ECMAScript Objects + + Unless specified otherwise in this document, the objects, functions, and constructors + described in this standard are subject to the generic requirements and restrictions + specified for standard built-in ECMAScript objects in the ECMAScript 2018 Language + Specification, 9th edition, clause 17, or successor. + + 17 ECMAScript Standard Built-in Objects: + + Every other data property described in clauses 18 through 26 and in Annex B.2 has the + attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } + unless otherwise specified. + +includes: [propertyHelper.js] +---*/ + +verifyNotEnumerable(Intl.DateTimeFormat.prototype, "constructor"); +verifyWritable(Intl.DateTimeFormat.prototype, "constructor"); +verifyConfigurable(Intl.DateTimeFormat.prototype, "constructor"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/shell.js diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/value.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/value.js new file mode 100644 index 0000000000..5092db0768 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/constructor/value.js @@ -0,0 +1,14 @@ +// Copyright 2012 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 12.3.1 +description: > + Tests that Intl.DateTimeFormat.prototype.constructor is the + Intl.DateTimeFormat. +author: Roozbeh Pournader +---*/ + +assert.sameValue(Intl.DateTimeFormat.prototype.constructor, Intl.DateTimeFormat, "Intl.DateTimeFormat.prototype.constructor is not the same as Intl.DateTimeFormat"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/bound-to-datetimeformat-instance.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/bound-to-datetimeformat-instance.js new file mode 100644 index 0000000000..485a7c0720 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/bound-to-datetimeformat-instance.js @@ -0,0 +1,30 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 12.3.2_1_c +description: Tests that format function is bound to its Intl.DateTimeFormat. +author: Norbert Lindenberg +---*/ + +var dates = [new Date(), new Date(0), new Date(Date.parse("1989-11-09T17:57:00Z"))]; +var locales = [undefined, ["de"], ["th-u-ca-gregory-nu-thai"], ["en"], ["ja-u-ca-japanese"], ["ar-u-ca-islamicc-nu-arab"]]; +var options = [ + undefined, + {hour12: false}, + {month: "long", day: "numeric", hour: "2-digit", minute: "2-digit"} +]; + +locales.forEach(function (locales) { + options.forEach(function (options) { + var formatObj = new Intl.DateTimeFormat(locales, options); + var formatFunc = formatObj.format; + dates.forEach(function (date) { + var referenceFormatted = formatObj.format(date); + var formatted = formatFunc(date); + assert.sameValue(referenceFormatted, formatted, "format function produces different result than format method for locales " + locales + "; options: " + (options ? JSON.stringify(options) : options) + "."); + }); + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/browser.js diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/builtin.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/builtin.js new file mode 100644 index 0000000000..c4870b0b57 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/builtin.js @@ -0,0 +1,33 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +es5id: 12.3.2_L15 +description: > + Tests that the getter for Intl.DateTimeFormat.prototype.format + meets the requirements for built-in objects defined by the + introduction of chapter 17 of the ECMAScript Language + Specification. +author: Norbert Lindenberg +includes: [isConstructor.js] +features: [Reflect.construct] +---*/ + +var formatFn = Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, "format").get; + +assert.sameValue(Object.prototype.toString.call(formatFn), "[object Function]", + "The [[Class]] internal property of a built-in function must be " + + "\"Function\"."); + +assert(Object.isExtensible(formatFn), + "Built-in objects must be extensible."); + +assert.sameValue(Object.getPrototypeOf(formatFn), Function.prototype); + +assert.sameValue(formatFn.hasOwnProperty("prototype"), false, + "Built-in functions that aren't constructors must not have a prototype property."); + +assert.sameValue(isConstructor(formatFn), false, + "Built-in functions don't implement [[Construct]] unless explicitly specified."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/date-constructor-not-called.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/date-constructor-not-called.js new file mode 100644 index 0000000000..f13f9425ce --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/date-constructor-not-called.js @@ -0,0 +1,38 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimepattern +description: | + The Date constructor is not called to convert the input value. +info: > + 12.1.5 DateTime Format Functions + + ... + 3. If date is not provided or is undefined, then + ... + 4. Else, + a. Let x be ? ToNumber(date). + 5. Return FormatDateTime(dtf, x). + + 12.1.6 PartitionDateTimePattern ( dateTimeFormat, x ) + + 1. Let x be TimeClip(x). + 2. If x is NaN, throw a RangeError exception. + 3. ... +---*/ + +var dtf = new Intl.DateTimeFormat(); + +var dateTimeString = "2017-11-10T14:09:00.000Z"; + +// |dateTimeString| is valid ISO-8601 style date/time string. +assert.notSameValue(new Date(dateTimeString), NaN); + +// Ensure string input values are not converted to time values by calling the +// Date constructor. +assert.throws(RangeError, function() { + dtf.format(dateTimeString); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-long-en.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-long-en.js new file mode 100644 index 0000000000..3af6285060 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-long-en.js @@ -0,0 +1,96 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet +// Copyright 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks basic handling of dayPeriod, long format. +features: [Intl.DateTimeFormat-dayPeriod] +locale: [en-US] +---*/ + +const d0000 = new Date(2017, 11, 12, 0, 0, 0, 0); +const d0100 = new Date(2017, 11, 12, 1, 0, 0, 0); +const d0200 = new Date(2017, 11, 12, 2, 0, 0, 0); +const d0300 = new Date(2017, 11, 12, 3, 0, 0, 0); +const d0400 = new Date(2017, 11, 12, 4, 0, 0, 0); +const d0500 = new Date(2017, 11, 12, 5, 0, 0, 0); +const d0600 = new Date(2017, 11, 12, 6, 0, 0, 0); +const d0700 = new Date(2017, 11, 12, 7, 0, 0, 0); +const d0800 = new Date(2017, 11, 12, 8, 0, 0, 0); +const d0900 = new Date(2017, 11, 12, 9, 0, 0, 0); +const d1000 = new Date(2017, 11, 12, 10, 0, 0, 0); +const d1100 = new Date(2017, 11, 12, 11, 0, 0, 0); +const d1200 = new Date(2017, 11, 12, 12, 0, 0, 0); +const d1300 = new Date(2017, 11, 12, 13, 0, 0, 0); +const d1400 = new Date(2017, 11, 12, 14, 0, 0, 0); +const d1500 = new Date(2017, 11, 12, 15, 0, 0, 0); +const d1600 = new Date(2017, 11, 12, 16, 0, 0, 0); +const d1700 = new Date(2017, 11, 12, 17, 0, 0, 0); +const d1800 = new Date(2017, 11, 12, 18, 0, 0, 0); +const d1900 = new Date(2017, 11, 12, 19, 0, 0, 0); +const d2000 = new Date(2017, 11, 12, 20, 0, 0, 0); +const d2100 = new Date(2017, 11, 12, 21, 0, 0, 0); +const d2200 = new Date(2017, 11, 12, 22, 0, 0, 0); +const d2300 = new Date(2017, 11, 12, 23, 0, 0, 0); + +const long = new Intl.DateTimeFormat('en', { + dayPeriod: 'long' +}); + +assert.sameValue(long.format(d0000), 'at night', '00:00, long format'); +assert.sameValue(long.format(d0100), 'at night', '01:00, long format'); +assert.sameValue(long.format(d0200), 'at night', '02:00, long format'); +assert.sameValue(long.format(d0300), 'at night', '03:00, long format'); +assert.sameValue(long.format(d0400), 'at night', '04:00, long format'); +assert.sameValue(long.format(d0500), 'at night', '05:00, long format'); +assert.sameValue(long.format(d0600), 'in the morning', '06:00, long format'); +assert.sameValue(long.format(d0700), 'in the morning', '07:00, long format'); +assert.sameValue(long.format(d0800), 'in the morning', '08:00, long format'); +assert.sameValue(long.format(d0900), 'in the morning', '09:00, long format'); +assert.sameValue(long.format(d1000), 'in the morning', '10:00, long format'); +assert.sameValue(long.format(d1100), 'in the morning', '11:00, long format'); +assert.sameValue(long.format(d1200), 'noon', '12:00, long format'); +assert.sameValue(long.format(d1300), 'in the afternoon', '13:00, long format'); +assert.sameValue(long.format(d1400), 'in the afternoon', '14:00, long format'); +assert.sameValue(long.format(d1500), 'in the afternoon', '15:00, long format'); +assert.sameValue(long.format(d1600), 'in the afternoon', '16:00, long format'); +assert.sameValue(long.format(d1700), 'in the afternoon', '17:00, long format'); +assert.sameValue(long.format(d1800), 'in the evening', '18:00, long format'); +assert.sameValue(long.format(d1900), 'in the evening', '19:00, long format'); +assert.sameValue(long.format(d2000), 'in the evening', '20:00, long format'); +assert.sameValue(long.format(d2100), 'at night', '21:00, long format'); +assert.sameValue(long.format(d2200), 'at night', '22:00, long format'); +assert.sameValue(long.format(d2300), 'at night', '23:00, long format'); + +const longNumeric = new Intl.DateTimeFormat('en', { + dayPeriod: 'long', + hour: 'numeric' +}); + +assert.sameValue(longNumeric.format(d0000), '12 at night', '00:00, long-numeric'); +assert.sameValue(longNumeric.format(d0100), '1 at night', '01:00, long-numeric'); +assert.sameValue(longNumeric.format(d0200), '2 at night', '02:00, long-numeric'); +assert.sameValue(longNumeric.format(d0300), '3 at night', '03:00, long-numeric'); +assert.sameValue(longNumeric.format(d0400), '4 at night', '04:00, long-numeric'); +assert.sameValue(longNumeric.format(d0500), '5 at night', '05:00, long-numeric'); +assert.sameValue(longNumeric.format(d0600), '6 in the morning', '06:00, long-numeric'); +assert.sameValue(longNumeric.format(d0700), '7 in the morning', '07:00, long-numeric'); +assert.sameValue(longNumeric.format(d0800), '8 in the morning', '08:00, long-numeric'); +assert.sameValue(longNumeric.format(d0900), '9 in the morning', '09:00, long-numeric'); +assert.sameValue(longNumeric.format(d1000), '10 in the morning', '10:00, long-numeric'); +assert.sameValue(longNumeric.format(d1100), '11 in the morning', '11:00, long-numeric'); +assert.sameValue(longNumeric.format(d1200), '12 noon', '12:00, long-numeric'); +assert.sameValue(longNumeric.format(d1300), '1 in the afternoon', '13:00, long-numeric'); +assert.sameValue(longNumeric.format(d1400), '2 in the afternoon', '14:00, long-numeric'); +assert.sameValue(longNumeric.format(d1500), '3 in the afternoon', '15:00, long-numeric'); +assert.sameValue(longNumeric.format(d1600), '4 in the afternoon', '16:00, long-numeric'); +assert.sameValue(longNumeric.format(d1700), '5 in the afternoon', '17:00, long-numeric'); +assert.sameValue(longNumeric.format(d1800), '6 in the evening', '18:00, long-numeric'); +assert.sameValue(longNumeric.format(d1900), '7 in the evening', '19:00, long-numeric'); +assert.sameValue(longNumeric.format(d2000), '8 in the evening', '20:00, long-numeric'); +assert.sameValue(longNumeric.format(d2100), '9 at night', '21:00, long-numeric'); +assert.sameValue(longNumeric.format(d2200), '10 at night', '22:00, long-numeric'); +assert.sameValue(longNumeric.format(d2300), '11 at night', '23:00, long-numeric'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-narrow-en.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-narrow-en.js new file mode 100644 index 0000000000..9ab465db89 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-narrow-en.js @@ -0,0 +1,96 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet +// Copyright 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks basic handling of dayPeriod, narrow format. +features: [Intl.DateTimeFormat-dayPeriod] +locale: [en-US] +---*/ + +const d0000 = new Date(2017, 11, 12, 0, 0, 0, 0); +const d0100 = new Date(2017, 11, 12, 1, 0, 0, 0); +const d0200 = new Date(2017, 11, 12, 2, 0, 0, 0); +const d0300 = new Date(2017, 11, 12, 3, 0, 0, 0); +const d0400 = new Date(2017, 11, 12, 4, 0, 0, 0); +const d0500 = new Date(2017, 11, 12, 5, 0, 0, 0); +const d0600 = new Date(2017, 11, 12, 6, 0, 0, 0); +const d0700 = new Date(2017, 11, 12, 7, 0, 0, 0); +const d0800 = new Date(2017, 11, 12, 8, 0, 0, 0); +const d0900 = new Date(2017, 11, 12, 9, 0, 0, 0); +const d1000 = new Date(2017, 11, 12, 10, 0, 0, 0); +const d1100 = new Date(2017, 11, 12, 11, 0, 0, 0); +const d1200 = new Date(2017, 11, 12, 12, 0, 0, 0); +const d1300 = new Date(2017, 11, 12, 13, 0, 0, 0); +const d1400 = new Date(2017, 11, 12, 14, 0, 0, 0); +const d1500 = new Date(2017, 11, 12, 15, 0, 0, 0); +const d1600 = new Date(2017, 11, 12, 16, 0, 0, 0); +const d1700 = new Date(2017, 11, 12, 17, 0, 0, 0); +const d1800 = new Date(2017, 11, 12, 18, 0, 0, 0); +const d1900 = new Date(2017, 11, 12, 19, 0, 0, 0); +const d2000 = new Date(2017, 11, 12, 20, 0, 0, 0); +const d2100 = new Date(2017, 11, 12, 21, 0, 0, 0); +const d2200 = new Date(2017, 11, 12, 22, 0, 0, 0); +const d2300 = new Date(2017, 11, 12, 23, 0, 0, 0); + +const narrow = new Intl.DateTimeFormat('en', { + dayPeriod: 'narrow' +}); + +assert.sameValue(narrow.format(d0000), 'at night', '00:00, narrow format'); +assert.sameValue(narrow.format(d0100), 'at night', '01:00, narrow format'); +assert.sameValue(narrow.format(d0200), 'at night', '02:00, narrow format'); +assert.sameValue(narrow.format(d0300), 'at night', '03:00, narrow format'); +assert.sameValue(narrow.format(d0400), 'at night', '04:00, narrow format'); +assert.sameValue(narrow.format(d0500), 'at night', '05:00, narrow format'); +assert.sameValue(narrow.format(d0600), 'in the morning', '06:00, narrow format'); +assert.sameValue(narrow.format(d0700), 'in the morning', '07:00, narrow format'); +assert.sameValue(narrow.format(d0800), 'in the morning', '08:00, narrow format'); +assert.sameValue(narrow.format(d0900), 'in the morning', '09:00, narrow format'); +assert.sameValue(narrow.format(d1000), 'in the morning', '10:00, narrow format'); +assert.sameValue(narrow.format(d1100), 'in the morning', '11:00, narrow format'); +assert.sameValue(narrow.format(d1200), 'n', '12:00, narrow format'); +assert.sameValue(narrow.format(d1300), 'in the afternoon', '13:00, narrow format'); +assert.sameValue(narrow.format(d1400), 'in the afternoon', '14:00, narrow format'); +assert.sameValue(narrow.format(d1500), 'in the afternoon', '15:00, narrow format'); +assert.sameValue(narrow.format(d1600), 'in the afternoon', '16:00, narrow format'); +assert.sameValue(narrow.format(d1700), 'in the afternoon', '17:00, narrow format'); +assert.sameValue(narrow.format(d1800), 'in the evening', '18:00, narrow format'); +assert.sameValue(narrow.format(d1900), 'in the evening', '19:00, narrow format'); +assert.sameValue(narrow.format(d2000), 'in the evening', '20:00, narrow format'); +assert.sameValue(narrow.format(d2100), 'at night', '21:00, narrow format'); +assert.sameValue(narrow.format(d2200), 'at night', '22:00, narrow format'); +assert.sameValue(narrow.format(d2300), 'at night', '23:00, narrow format'); + +const narrowNumeric = new Intl.DateTimeFormat('en', { + dayPeriod: 'narrow', + hour: 'numeric' +}); + +assert.sameValue(narrowNumeric.format(d0000), '12 at night', '00:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d0100), '1 at night', '01:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d0200), '2 at night', '02:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d0300), '3 at night', '03:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d0400), '4 at night', '04:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d0500), '5 at night', '05:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d0600), '6 in the morning', '06:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d0700), '7 in the morning', '07:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d0800), '8 in the morning', '08:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d0900), '9 in the morning', '09:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d1000), '10 in the morning', '10:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d1100), '11 in the morning', '11:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d1200), '12 n', '12:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d1300), '1 in the afternoon', '13:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d1400), '2 in the afternoon', '14:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d1500), '3 in the afternoon', '15:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d1600), '4 in the afternoon', '16:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d1700), '5 in the afternoon', '17:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d1800), '6 in the evening', '18:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d1900), '7 in the evening', '19:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d2000), '8 in the evening', '20:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d2100), '9 at night', '21:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d2200), '10 at night', '22:00, narrow-numeric'); +assert.sameValue(narrowNumeric.format(d2300), '11 at night', '23:00, narrow-numeric'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-short-en.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-short-en.js new file mode 100644 index 0000000000..c950aee0ca --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/dayPeriod-short-en.js @@ -0,0 +1,96 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet +// Copyright 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks basic handling of dayPeriod, short format. +features: [Intl.DateTimeFormat-dayPeriod] +locale: [en-US] +---*/ + +const d0000 = new Date(2017, 11, 12, 0, 0, 0, 0); +const d0100 = new Date(2017, 11, 12, 1, 0, 0, 0); +const d0200 = new Date(2017, 11, 12, 2, 0, 0, 0); +const d0300 = new Date(2017, 11, 12, 3, 0, 0, 0); +const d0400 = new Date(2017, 11, 12, 4, 0, 0, 0); +const d0500 = new Date(2017, 11, 12, 5, 0, 0, 0); +const d0600 = new Date(2017, 11, 12, 6, 0, 0, 0); +const d0700 = new Date(2017, 11, 12, 7, 0, 0, 0); +const d0800 = new Date(2017, 11, 12, 8, 0, 0, 0); +const d0900 = new Date(2017, 11, 12, 9, 0, 0, 0); +const d1000 = new Date(2017, 11, 12, 10, 0, 0, 0); +const d1100 = new Date(2017, 11, 12, 11, 0, 0, 0); +const d1200 = new Date(2017, 11, 12, 12, 0, 0, 0); +const d1300 = new Date(2017, 11, 12, 13, 0, 0, 0); +const d1400 = new Date(2017, 11, 12, 14, 0, 0, 0); +const d1500 = new Date(2017, 11, 12, 15, 0, 0, 0); +const d1600 = new Date(2017, 11, 12, 16, 0, 0, 0); +const d1700 = new Date(2017, 11, 12, 17, 0, 0, 0); +const d1800 = new Date(2017, 11, 12, 18, 0, 0, 0); +const d1900 = new Date(2017, 11, 12, 19, 0, 0, 0); +const d2000 = new Date(2017, 11, 12, 20, 0, 0, 0); +const d2100 = new Date(2017, 11, 12, 21, 0, 0, 0); +const d2200 = new Date(2017, 11, 12, 22, 0, 0, 0); +const d2300 = new Date(2017, 11, 12, 23, 0, 0, 0); + +const short = new Intl.DateTimeFormat('en', { + dayPeriod: 'short' +}); + +assert.sameValue(short.format(d0000), 'at night', '00:00, short format'); +assert.sameValue(short.format(d0100), 'at night', '01:00, short format'); +assert.sameValue(short.format(d0200), 'at night', '02:00, short format'); +assert.sameValue(short.format(d0300), 'at night', '03:00, short format'); +assert.sameValue(short.format(d0400), 'at night', '04:00, short format'); +assert.sameValue(short.format(d0500), 'at night', '05:00, short format'); +assert.sameValue(short.format(d0600), 'in the morning', '06:00, short format'); +assert.sameValue(short.format(d0700), 'in the morning', '07:00, short format'); +assert.sameValue(short.format(d0800), 'in the morning', '08:00, short format'); +assert.sameValue(short.format(d0900), 'in the morning', '09:00, short format'); +assert.sameValue(short.format(d1000), 'in the morning', '10:00, short format'); +assert.sameValue(short.format(d1100), 'in the morning', '11:00, short format'); +assert.sameValue(short.format(d1200), 'noon', '12:00, short format'); +assert.sameValue(short.format(d1300), 'in the afternoon', '13:00, short format'); +assert.sameValue(short.format(d1400), 'in the afternoon', '14:00, short format'); +assert.sameValue(short.format(d1500), 'in the afternoon', '15:00, short format'); +assert.sameValue(short.format(d1600), 'in the afternoon', '16:00, short format'); +assert.sameValue(short.format(d1700), 'in the afternoon', '17:00, short format'); +assert.sameValue(short.format(d1800), 'in the evening', '18:00, short format'); +assert.sameValue(short.format(d1900), 'in the evening', '19:00, short format'); +assert.sameValue(short.format(d2000), 'in the evening', '20:00, short format'); +assert.sameValue(short.format(d2100), 'at night', '21:00, short format'); +assert.sameValue(short.format(d2200), 'at night', '22:00, short format'); +assert.sameValue(short.format(d2300), 'at night', '23:00, short format'); + +const shortNumeric = new Intl.DateTimeFormat('en', { + dayPeriod: 'short', + hour: 'numeric' +}); + +assert.sameValue(shortNumeric.format(d0000), '12 at night', '00:00, short-numeric'); +assert.sameValue(shortNumeric.format(d0100), '1 at night', '01:00, short-numeric'); +assert.sameValue(shortNumeric.format(d0200), '2 at night', '02:00, short-numeric'); +assert.sameValue(shortNumeric.format(d0300), '3 at night', '03:00, short-numeric'); +assert.sameValue(shortNumeric.format(d0400), '4 at night', '04:00, short-numeric'); +assert.sameValue(shortNumeric.format(d0500), '5 at night', '05:00, short-numeric'); +assert.sameValue(shortNumeric.format(d0600), '6 in the morning', '06:00, short-numeric'); +assert.sameValue(shortNumeric.format(d0700), '7 in the morning', '07:00, short-numeric'); +assert.sameValue(shortNumeric.format(d0800), '8 in the morning', '08:00, short-numeric'); +assert.sameValue(shortNumeric.format(d0900), '9 in the morning', '09:00, short-numeric'); +assert.sameValue(shortNumeric.format(d1000), '10 in the morning', '10:00, short-numeric'); +assert.sameValue(shortNumeric.format(d1100), '11 in the morning', '11:00, short-numeric'); +assert.sameValue(shortNumeric.format(d1200), '12 noon', '12:00, short-numeric'); +assert.sameValue(shortNumeric.format(d1300), '1 in the afternoon', '13:00, short-numeric'); +assert.sameValue(shortNumeric.format(d1400), '2 in the afternoon', '14:00, short-numeric'); +assert.sameValue(shortNumeric.format(d1500), '3 in the afternoon', '15:00, short-numeric'); +assert.sameValue(shortNumeric.format(d1600), '4 in the afternoon', '16:00, short-numeric'); +assert.sameValue(shortNumeric.format(d1700), '5 in the afternoon', '17:00, short-numeric'); +assert.sameValue(shortNumeric.format(d1800), '6 in the evening', '18:00, short-numeric'); +assert.sameValue(shortNumeric.format(d1900), '7 in the evening', '19:00, short-numeric'); +assert.sameValue(shortNumeric.format(d2000), '8 in the evening', '20:00, short-numeric'); +assert.sameValue(shortNumeric.format(d2100), '9 at night', '21:00, short-numeric'); +assert.sameValue(shortNumeric.format(d2200), '10 at night', '22:00, short-numeric'); +assert.sameValue(shortNumeric.format(d2300), '11 at night', '23:00, short-numeric'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-builtin.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-builtin.js new file mode 100644 index 0000000000..d5270e354a --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-builtin.js @@ -0,0 +1,33 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +es5id: 12.3.2_1_a_L15 +description: > + Tests that the function returned by + Intl.DateTimeFormat.prototype.format meets the requirements for + built-in objects defined by the introduction of chapter 17 of the + ECMAScript Language Specification. +author: Norbert Lindenberg +includes: [isConstructor.js] +features: [Reflect.construct] +---*/ + +var formatFn = new Intl.DateTimeFormat().format; + +assert.sameValue(Object.prototype.toString.call(formatFn), "[object Function]", + "The [[Class]] internal property of a built-in function must be " + + "\"Function\"."); + +assert(Object.isExtensible(formatFn), + "Built-in objects must be extensible."); + +assert.sameValue(Object.getPrototypeOf(formatFn), Function.prototype); + +assert.sameValue(formatFn.hasOwnProperty("prototype"), false, + "Built-in functions that aren't constructors must not have a prototype property."); + +assert.sameValue(isConstructor(formatFn), false, + "Built-in functions don't implement [[Construct]] unless explicitly specified."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-length.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-length.js new file mode 100644 index 0000000000..805c197144 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-length.js @@ -0,0 +1,30 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype.format +description: > + The length of the bound DateTime Format function is 1. +info: | + get Intl.DateTimeFormat.prototype.format + + ... + 4. If dtf.[[BoundFormat]] is undefined, then + a. Let F be a new built-in function object as defined in DateTime Format Functions (12.1.5). + b. Let bf be BoundFunctionCreate(F, dft, « »). + c. Perform ! DefinePropertyOrThrow(bf, "length", PropertyDescriptor {[[Value]]: 1, + [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true}). + ... + +includes: [propertyHelper.js] +---*/ + +var formatFn = new Intl.DateTimeFormat().format; + +assert.sameValue(formatFn.length, 1); + +verifyNotEnumerable(formatFn, "length"); +verifyNotWritable(formatFn, "length"); +verifyConfigurable(formatFn, "length"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-name.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-name.js new file mode 100644 index 0000000000..73922bca5f --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/format-function-name.js @@ -0,0 +1,28 @@ +// Copyright (C) 2016 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DateTimeFormat.prototype.format +description: > + The bound DateTimeFormat format function is an anonymous function. +info: | + 12.4.3 get Intl.DateTimeFormat.prototype.compare + + 17 ECMAScript Standard Built-in Objects: + Every built-in function object, including constructors, has a `name` + property whose value is a String. Functions that are identified as + anonymous functions use the empty string as the value of the `name` + property. + Unless otherwise specified, the `name` property of a built-in function + object has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, + [[Configurable]]: *true* }. +includes: [propertyHelper.js] +---*/ + +var formatFn = new Intl.DateTimeFormat().format; + +verifyProperty(formatFn, "name", { + value: "", writable: false, enumerable: false, configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/fractionalSecondDigits.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/fractionalSecondDigits.js new file mode 100644 index 0000000000..4d5b8db882 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/fractionalSecondDigits.js @@ -0,0 +1,34 @@ +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks basic handling of fractionalSecondDigits. +features: [Intl.DateTimeFormat-fractionalSecondDigits] +locale: [en-US] +---*/ + +const d1 = new Date(2019, 7, 10, 1, 2, 3, 234); +const d2 = new Date(2019, 7, 10, 1, 2, 3, 567); + +let dtf = new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: undefined}); +assert.sameValue(dtf.format(d1), "02:03", "no fractionalSecondDigits"); +assert.sameValue(dtf.format(d2), "02:03", "no fractionalSecondDigits"); + +dtf = new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 1}); +assert.sameValue(dtf.format(d1), "02:03.2", "1 fractionalSecondDigits round down"); +assert.sameValue(dtf.format(d2), "02:03.5", "1 fractionalSecondDigits round down"); + +dtf = new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 2}); +assert.sameValue(dtf.format(d1), "02:03.23", "2 fractionalSecondDigits round down"); +assert.sameValue(dtf.format(d2), "02:03.56", "2 fractionalSecondDigits round down"); + +dtf = new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 3}); +assert.sameValue(dtf.format(d1), "02:03.234", "3 fractionalSecondDigits round down"); +assert.sameValue(dtf.format(d2), "02:03.567", "3 fractionalSecondDigits round down"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/length.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/length.js new file mode 100644 index 0000000000..9b9ff002b1 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/length.js @@ -0,0 +1,35 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype.format +description: > + get Intl.DateTimeFormat.prototype.format.length is 0. +info: | + get Intl.DateTimeFormat.prototype.format + + 17 ECMAScript Standard Built-in Objects: + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + Unless otherwise specified, the length property of a built-in function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. + +includes: [propertyHelper.js] +---*/ + +var desc = Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, "format"); + +assert.sameValue(desc.get.length, 0); + +verifyNotEnumerable(desc.get, "length"); +verifyNotWritable(desc.get, "length"); +verifyConfigurable(desc.get, "length"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/name.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/name.js new file mode 100644 index 0000000000..3729320d39 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/name.js @@ -0,0 +1,30 @@ +// Copyright (C) 2016 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DateTimeFormat.prototype.format +description: > + get Intl.DateTimeFormat.prototype.format.name is "get format". +info: | + 12.4.3 get Intl.DateTimeFormat.prototype.format + + 17 ECMAScript Standard Built-in Objects: + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +---*/ + +var desc = Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, "format"); + +assert.sameValue(desc.get.name, "get format"); + +verifyNotEnumerable(desc.get, "name"); +verifyNotWritable(desc.get, "name"); +verifyConfigurable(desc.get, "name"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/proleptic-gregorian-calendar.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/proleptic-gregorian-calendar.js new file mode 100644 index 0000000000..0a76e32cab --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/proleptic-gregorian-calendar.js @@ -0,0 +1,31 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 12.3.2_FDT_7_a_iv +description: > + Tests that format uses a proleptic Gregorian calendar with no year + 0. +author: Norbert Lindenberg +---*/ + +var dates = [ + 0, // January 1, 1970 + -62151602400000, // in June 1 BC + -8640000000000000 // beginning of ECMAScript time +]; + +var format = new Intl.DateTimeFormat(["en-US"], {year: "numeric", month: "long", timeZone: "UTC"}); + +// this test requires a Gregorian calendar, which we usually find in the US +assert.sameValue(format.resolvedOptions().calendar, "gregory", "Internal error: Didn't find Gregorian calendar"); + +dates.forEach(function (date) { + var year = new Date(date).getUTCFullYear(); + var expectedYear = year <= 0 ? 1 - year : year; + var expectedYearString = expectedYear.toLocaleString(["en-US"], {useGrouping: false}); + var dateString = format.format(date); + assert.notSameValue(dateString.indexOf(expectedYearString), -1, "Formatted year doesn't contain expected year – expected " + expectedYearString + ", got " + dateString + "."); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/prop-desc.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/prop-desc.js new file mode 100644 index 0000000000..737d4841a2 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/prop-desc.js @@ -0,0 +1,37 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype.format +description: > + "format" property of Intl.DateTimeFormat.prototype. +info: | + get Intl.DateTimeFormat.prototype.format + + 7 Requirements for Standard Built-in ECMAScript Objects + + Unless specified otherwise in this document, the objects, functions, and constructors + described in this standard are subject to the generic requirements and restrictions + specified for standard built-in ECMAScript objects in the ECMAScript 2018 Language + Specification, 9th edition, clause 17, or successor. + + 17 ECMAScript Standard Built-in Objects: + + Every accessor property described in clauses 18 through 26 and in Annex B.2 has the + attributes { [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. + If only a get accessor function is described, the set accessor function is the default + value, undefined. If only a set accessor is described the get accessor is the default + value, undefined. + +includes: [propertyHelper.js] +---*/ + +var desc = Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, "format"); + +assert.sameValue(desc.set, undefined); +assert.sameValue(typeof desc.get, "function"); + +verifyNotEnumerable(Intl.DateTimeFormat.prototype, "format"); +verifyConfigurable(Intl.DateTimeFormat.prototype, "format"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/related-year-zh.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/related-year-zh.js new file mode 100644 index 0000000000..eba77bf9e9 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/related-year-zh.js @@ -0,0 +1,19 @@ +// Copyright 2019 Google Inc, Igalia S.L. All rights reserved. +// Copyright 2020 Apple Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimepattern +description: > + Checks the output of 'relatedYear' and 'yearName' type, and + the choice of pattern based on calendar. +locale: [zh-u-ca-chinese] +---*/ + +const df = new Intl.DateTimeFormat("zh-u-ca-chinese", {year: "numeric"}); +const date = new Date(2019, 5, 1); +const formatted = df.format(date); +const expected = ["2019己亥年", "己亥年"]; +assert(expected.includes(formatted)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/shell.js new file mode 100644 index 0000000000..a96394ce86 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/shell.js @@ -0,0 +1,50 @@ +// GENERATED, DO NOT EDIT +// file: dateConstants.js +// Copyright (C) 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + Collection of date-centric values +defines: + - date_1899_end + - date_1900_start + - date_1969_end + - date_1970_start + - date_1999_end + - date_2000_start + - date_2099_end + - date_2100_start + - start_of_time + - end_of_time +---*/ + +var date_1899_end = -2208988800001; +var date_1900_start = -2208988800000; +var date_1969_end = -1; +var date_1970_start = 0; +var date_1999_end = 946684799999; +var date_2000_start = 946684800000; +var date_2099_end = 4102444799999; +var date_2100_start = 4102444800000; + +var start_of_time = -8.64e15; +var end_of_time = 8.64e15; + +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +---*/ + +function isConstructor(f) { + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/taint-Object-prototype.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/taint-Object-prototype.js new file mode 100644 index 0000000000..b4ca8b4b0d --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/taint-Object-prototype.js @@ -0,0 +1,18 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 12.3.2_TLT_2 +description: > + Tests that the behavior of a Record is not affected by + adversarial changes to Object.prototype. +author: Norbert Lindenberg +includes: [testIntl.js] +---*/ + +taintProperties(["weekday", "era", "year", "month", "day", "hour", "minute", "second", "inDST"]); + +var format = new Intl.DateTimeFormat(); +var time = format.format(); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/throws-value-non-finite.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/throws-value-non-finite.js new file mode 100644 index 0000000000..598b9ec88e --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/throws-value-non-finite.js @@ -0,0 +1,20 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 12.3.2_FDT_1 +description: Tests that format handles non-finite values correctly. +author: Norbert Lindenberg +---*/ + +var invalidValues = [NaN, Infinity, -Infinity]; + +var format = new Intl.DateTimeFormat(); + +invalidValues.forEach(function (value) { + assert.throws(RangeError, function() { + var result = format.format(value); + }, "Invalid value " + value + " was not rejected."); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/time-clip-near-time-boundaries.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/time-clip-near-time-boundaries.js new file mode 100644 index 0000000000..0c415ec7ea --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/time-clip-near-time-boundaries.js @@ -0,0 +1,39 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimepattern +description: | + TimeClip is applied when calling Intl.DateTimeFormat.prototype.format. +info: > + 12.1.6 PartitionDateTimePattern ( dateTimeFormat, x ) + + 1. Let x be TimeClip(x). + 2. If x is NaN, throw a RangeError exception. + 3. ... + + 20.3.1.15 TimeClip ( time ) + ... + 2. If abs(time) > 8.64 × 10^15, return NaN. + ... + +includes: [dateConstants.js] +---*/ + +var dtf = new Intl.DateTimeFormat(); + +// Test values near the start of the ECMAScript time range. +assert.throws(RangeError, function() { + dtf.format(start_of_time - 1); +}); +assert.sameValue(typeof dtf.format(start_of_time), "string"); +assert.sameValue(typeof dtf.format(start_of_time + 1), "string"); + +// Test values near the end of the ECMAScript time range. +assert.sameValue(typeof dtf.format(end_of_time - 1), "string"); +assert.sameValue(typeof dtf.format(end_of_time), "string"); +assert.throws(RangeError, function() { + dtf.format(end_of_time + 1); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/time-clip-to-integer.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/time-clip-to-integer.js new file mode 100644 index 0000000000..d7fbe4db66 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/time-clip-to-integer.js @@ -0,0 +1,39 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimepattern +description: | + TimeClip applies ToInteger on its input value. +info: > + 12.1.6 PartitionDateTimePattern ( dateTimeFormat, x ) + + 1. Let x be TimeClip(x). + 2. ... + + 20.3.1.15 TimeClip ( time ) + ... + 3. Let clippedTime be ! ToInteger(time). + 4. If clippedTime is -0, set clippedTime to +0. + 5. Return clippedTime. +---*/ + +// Switch to a time format instead of using DateTimeFormat's default date-only format. +var dtf = new Intl.DateTimeFormat(undefined, { + hour: "numeric", minute: "numeric", second: "numeric" +}); + +var expected = dtf.format(0); + +assert.sameValue(dtf.format(-0.9), expected, "format(-0.9)"); +assert.sameValue(dtf.format(-0.5), expected, "format(-0.5)"); +assert.sameValue(dtf.format(-0.1), expected, "format(-0.1)"); +assert.sameValue(dtf.format(-Number.MIN_VALUE), expected, "format(-Number.MIN_VALUE)"); +assert.sameValue(dtf.format(-0), expected, "format(-0)"); +assert.sameValue(dtf.format(+0), expected, "format(+0)"); +assert.sameValue(dtf.format(Number.MIN_VALUE), expected, "format(Number.MIN_VALUE)"); +assert.sameValue(dtf.format(0.1), expected, "format(0.1)"); +assert.sameValue(dtf.format(0.5), expected, "format(0.5)"); +assert.sameValue(dtf.format(0.9), expected, "format(0.9)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/timedatestyle-en.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/timedatestyle-en.js new file mode 100644 index 0000000000..b51cb84475 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/timedatestyle-en.js @@ -0,0 +1,106 @@ +// Copyright 2019 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-date-time-style-pattern +description: Checks basic handling of timeStyle and dateStyle. +features: [Intl.DateTimeFormat-datetimestyle] +locale: [en-US] +---*/ + +const date = new Date("1886-05-01T14:12:47Z"); +const dateOptions = [ + ["full", "Saturday, May 1, 1886"], + ["long", "May 1, 1886"], + ["medium", "May 1, 1886"], + ["short", "5/1/86"], +]; + +const timeOptions = [ + ["full", "2:12:47 PM Coordinated Universal Time", "14:12:47 Coordinated Universal Time"], + ["long", "2:12:47 PM UTC", "14:12:47 UTC"], + ["medium", "2:12:47 PM", "14:12:47"], + ["short", "2:12 PM", "14:12"], +]; + +const options12 = [ + { "hour12": true }, + { "hourCycle": "h11" }, + { "hourCycle": "h12" }, + { "hourCycle": "h23", "hour12": true }, + { "hourCycle": "h24", "hour12": true }, +]; + +const options24 = [ + { "hour12": false }, + { "hourCycle": "h23" }, + { "hourCycle": "h24" }, + { "hourCycle": "h11", "hour12": false }, + { "hourCycle": "h12", "hour12": false }, +]; + +for (const [dateStyle, expected] of dateOptions) { + const dtf = new Intl.DateTimeFormat("en-US", { + dateStyle, + timeZone: "UTC", + }); + + const dateString = dtf.format(date); + assert.sameValue(dateString, expected, `Result for ${dateStyle}`); +} + +for (const [timeStyle, expected12, expected24] of timeOptions) { + const check = (locale, options, expected) => { + const dtf = new Intl.DateTimeFormat(locale, { + timeStyle, + timeZone: "UTC", + ...options + }); + + const dateString = dtf.format(date); + assert.sameValue(dateString, expected, `Result for ${timeStyle} with ${JSON.stringify(options)}`); + }; + + check("en-US", {}, expected12); + check("en-US-u-hc-h11", {}, expected12); + check("en-US-u-hc-h12", {}, expected12); + check("en-US-u-hc-h23", {}, expected24); + check("en-US-u-hc-h24", {}, expected24); + + for (const hourOptions of options12) { + check("en-US", hourOptions, expected12); + check("en-US-u-hc-h11", hourOptions, expected12); + check("en-US-u-hc-h12", hourOptions, expected12); + check("en-US-u-hc-h23", hourOptions, expected12); + check("en-US-u-hc-h24", hourOptions, expected12); + } + + for (const hourOptions of options24) { + check("en-US", hourOptions, expected24); + check("en-US-u-hc-h11", hourOptions, expected24); + check("en-US-u-hc-h12", hourOptions, expected24); + check("en-US-u-hc-h23", hourOptions, expected24); + check("en-US-u-hc-h24", hourOptions, expected24); + } +} + +for (const [dateStyle, expectedDate] of dateOptions) { + for (const [timeStyle, expectedTime] of timeOptions) { + const dtf = new Intl.DateTimeFormat("en-US", { + dateStyle, + timeStyle, + timeZone: "UTC", + }); + const result1 = [expectedDate, ", ", expectedTime].join(""); + const result2 = [expectedDate, " at ", expectedTime].join(""); + + const dateString = dtf.format(date); + assert.sameValue( + [result1, result2].includes(dateString), + true, + `Result for date=${dateStyle} and time=${timeStyle}` + ); + } +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-date-string.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-date-string.js new file mode 100644 index 0000000000..edbcbee2c6 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-date-string.js @@ -0,0 +1,42 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright (C) 2017 André Bargull. All rights reserved. +// Copyright (C) 2019 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimerangepattern +description: > + The Date constructor is not called to convert the input value. +info: | + Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate ) + + 5. Let x be ? ToNumber(startDate). + 6. Let y be ? ToNumber(endDate). + 8. Return ? FormatDateTimeRange(dtf, x, y). + + PartitionDateTimeRangePattern ( dateTimeFormat, x, y ) + + 1. Let x be TimeClip(x). + 2. If x is NaN, throw a RangeError exception. + 3. Let y be TimeClip(y). + 4. If y is NaN, throw a RangeError exception. +features: [Intl.DateTimeFormat-formatRange] +---*/ + +const dtf = new Intl.DateTimeFormat(); +const dateTimeString = "2017-11-10T14:09:00.000Z"; +const date = new Date(dateTimeString); +// |dateTimeString| is valid ISO-8601 style date/time string. +assert.notSameValue(date, NaN); + +// ToNumber() will try to parse the string as an integer and yield NaN, rather +// than attempting to parse it like the Date constructor would. +assert.throws(RangeError, function() { + dtf.formatRange(dateTimeString, date); +}); + +assert.throws(RangeError, function() { + dtf.formatRange(date, dateTimeString); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-near-time-boundaries.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-near-time-boundaries.js new file mode 100644 index 0000000000..3f0141ed42 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-near-time-boundaries.js @@ -0,0 +1,50 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright (C) 2017 André Bargull. All rights reserved. +// Copyright (C) 2019 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimerangepattern +description: > + TimeClip is applied when calling Intl.DateTimeFormat.prototype.formatRange. +info: | + PartitionDateTimeRangePattern ( dateTimeFormat, x, y ) + + 1. Let x be TimeClip(x). + 2. If x is NaN, throw a RangeError exception. + 3. Let y be TimeClip(y). + 4. If y is NaN, throw a RangeError exception. + + TimeClip ( time ) + ... + 2. If abs(time) > 8.64 × 10^15, return NaN. + ... + +includes: [dateConstants.js] +features: [Intl.DateTimeFormat-formatRange] +---*/ + +const dtf = new Intl.DateTimeFormat(); +const date = Date.now(); + +// Test values near the start of the ECMAScript time range. +assert.throws(RangeError, function() { + dtf.formatRange(start_of_time - 1, date); +}); +assert.throws(RangeError, function() { + dtf.formatRange(date, start_of_time - 1); +}); +assert.sameValue(typeof dtf.formatRange(start_of_time, date), "string"); +assert.sameValue(typeof dtf.formatRange(start_of_time + 1, date), "string"); + +// Test values near the end of the ECMAScript time range. +assert.sameValue(typeof dtf.formatRange(date, end_of_time - 1), "string"); +assert.sameValue(typeof dtf.formatRange(date, end_of_time), "string"); +assert.throws(RangeError, function() { + dtf.formatRange(end_of_time + 1, date); +}); +assert.throws(RangeError, function() { + dtf.formatRange(date, end_of_time + 1); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-to-integer.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-to-integer.js new file mode 100644 index 0000000000..adabb74dc7 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-to-integer.js @@ -0,0 +1,42 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright (C) 2017 André Bargull. All rights reserved. +// Copyright (C) 2019 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimerangepattern +description: > + TimeClip applies ToInteger on its input value. +info: | + Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate ) + + 5. Let x be ? ToNumber(startDate). + 6. Let y be ? ToNumber(endDate). + + TimeClip ( time ) + ... + 3. Let clippedTime be ! ToInteger(time). + 4. If clippedTime is -0, set clippedTime to +0. + 5. Return clippedTime. +features: [Intl.DateTimeFormat-formatRange] +---*/ + +// Switch to a time format instead of using DateTimeFormat's default date-only format. +const dtf = new Intl.DateTimeFormat(undefined, { + hour: "numeric", minute: "numeric", second: "numeric" +}); +const date = Date.now(); +const expected = dtf.formatRange(0, date); + +assert.sameValue(dtf.formatRange(-0.9, date), expected, "formatRange(-0.9)"); +assert.sameValue(dtf.formatRange(-0.5, date), expected, "formatRange(-0.5)"); +assert.sameValue(dtf.formatRange(-0.1, date), expected, "formatRange(-0.1)"); +assert.sameValue(dtf.formatRange(-Number.MIN_VALUE, date), expected, "formatRange(-Number.MIN_VALUE)"); +assert.sameValue(dtf.formatRange(-0, date), expected, "formatRange(-0)"); +assert.sameValue(dtf.formatRange(+0, date), expected, "formatRange(+0)"); +assert.sameValue(dtf.formatRange(Number.MIN_VALUE, date), expected, "formatRange(Number.MIN_VALUE)"); +assert.sameValue(dtf.formatRange(0.1, date), expected, "formatRange(0.1)"); +assert.sameValue(dtf.formatRange(0.5, date), expected, "formatRange(0.5)"); +assert.sameValue(dtf.formatRange(0.9, date), expected, "formatRange(0.9)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-tonumber-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-tonumber-throws.js new file mode 100644 index 0000000000..a0178e5b92 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/argument-tonumber-throws.js @@ -0,0 +1,57 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Igalia S.L. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +description: > + Return abrupt completions from ToNumber(date) +info: | + Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate ) + + 5. Let x be ? ToNumber(startDate). + 6. Let y be ? ToNumber(endDate). +features: [Symbol,Intl.DateTimeFormat-formatRange] +---*/ + +const date = Date.now(); + +const objectValueOf = { + valueOf: function() { + throw new Test262Error(); + } +}; + +const objectToString = { + toString: function() { + throw new Test262Error(); + } +}; + +const dtf = new Intl.DateTimeFormat(["pt-BR"]); + +assert.throws(Test262Error, function() { + dtf.formatRange(objectValueOf, date); +}, "valueOf start"); + +assert.throws(Test262Error, function() { + dtf.formatRange(date, objectValueOf); +}, "valueOf end"); + +assert.throws(Test262Error, function() { + dtf.formatRange(objectToString, date); +}, "toString start"); + +assert.throws(Test262Error, function() { + dtf.formatRange(date, objectToString); +}, "toString end"); + +const s = Symbol('1'); +assert.throws(TypeError, function() { + dtf.formatRange(s, date); +}, "symbol start"); + +assert.throws(TypeError, function() { + dtf.formatRange(date, s); +}, "symbol end"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/browser.js diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/builtin.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/builtin.js new file mode 100644 index 0000000000..2b42ca92ea --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/builtin.js @@ -0,0 +1,33 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2012 Mozilla Corporation. All rights reserved. +// Copyright 2019 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-ecmascript-standard-built-in-objects +description: > + Tests that the Intl.DateTimeFormat.prototype.formatRange function meets the + requirements for built-in objects defined by the ECMAScript Language + Specification. +includes: [isConstructor.js] +features: [Reflect.construct,Intl.DateTimeFormat-formatRange] +---*/ + +const formatRange = Intl.DateTimeFormat.prototype.formatRange; + +assert.sameValue(Object.prototype.toString.call(formatRange), "[object Function]", + "The [[Class]] internal property of a built-in function must be " + + "\"Function\"."); + +assert(Object.isExtensible(formatRange), + "Built-in objects must be extensible."); + +assert.sameValue(Object.getPrototypeOf(formatRange), Function.prototype); + +assert.sameValue(formatRange.hasOwnProperty("prototype"), false, + "Built-in functions that aren't constructors must not have a prototype property."); + +assert.sameValue(isConstructor(formatRange), false, + "Built-in functions don't implement [[Construct]] unless explicitly specified."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-is-infinity-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-is-infinity-throws.js new file mode 100644 index 0000000000..9ddfd159e8 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-is-infinity-throws.js @@ -0,0 +1,73 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Google, Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Throws a RangeError if date arg is cast to an Infinity value +info: | + Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate ) + + 1. Let dtf be this value. + 2. If Type(dtf) is not Object, throw a TypeError exception. + 3. If dtf does not have an [[InitializedDateTimeFormat]] internal slot, throw a TypeError exception. + 4. If startDate is undefined or endDate is undefined, throw a RangeError exception. + 5. Let x be ? ToNumber(startDate). + 6. Let y be ? ToNumber(endDate). + 7. If x is greater than y, throw a RangeError exception. + 8. Return ? FormatDateTimeRange(dtf, x, y). + + FormatDateTimeRange ( dateTimeFormat, x, y ) + + 1. Let parts be ? PartitionDateTimeRangePattern(dateTimeFormat, x, y). + + PartitionDateTimeRangePattern ( dateTimeFormat, x, y ) + + 1. Let x be TimeClip(x). + 2. If x is NaN, throw a RangeError exception. + 3. Let y be TimeClip(y). + 4. If y is NaN, throw a RangeError exception. + + TimeClip ( time ) + 1. If time is not finite, return NaN. + +features: [Intl.DateTimeFormat-formatRange] +---*/ + +var dtf = new Intl.DateTimeFormat(); + +var date = new Date(); + +assert.throws(RangeError, function() { + dtf.formatRange(Infinity, date); +}, "+Infinity/date"); + +assert.throws(RangeError, function() { + dtf.formatRange(-Infinity, date); +}, "-Infinity/date"); + +assert.throws(RangeError, function() { + dtf.formatRange(date, Infinity); +}, "date/+Infinity"); + +assert.throws(RangeError, function() { + dtf.formatRange(date, -Infinity); +}, "date/-Infinity"); + +assert.throws(RangeError, function() { + dtf.formatRange(Infinity, Infinity); +}, "+Infinity/+Infinity"); + +assert.throws(RangeError, function() { + dtf.formatRange(-Infinity, -Infinity); +}, "-Infinity/-Infinity"); + +assert.throws(RangeError, function() { + dtf.formatRange(Infinity, -Infinity); +}, "+Infinity/-Infinity"); + +assert.throws(RangeError, function() { + dtf.formatRange(-Infinity, Infinity); +}, "-Infinity/+Infinity"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-is-nan-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-is-nan-throws.js new file mode 100644 index 0000000000..52621dd1a4 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-is-nan-throws.js @@ -0,0 +1,50 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Google, Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Throws a RangeError if date arg is cast to NaN +info: | + Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate ) + + 1. Let dtf be this value. + 2. If Type(dtf) is not Object, throw a TypeError exception. + 3. If dtf does not have an [[InitializedDateTimeFormat]] internal slot, throw a TypeError exception. + 4. If startDate is undefined or endDate is undefined, throw a RangeError exception. + 5. Let x be ? ToNumber(startDate). + 6. Let y be ? ToNumber(endDate). + 7. If x is greater than y, throw a RangeError exception. + 8. Return ? FormatDateTimeRange(dtf, x, y). + + FormatDateTimeRange ( dateTimeFormat, x, y ) + + 1. Let parts be ? PartitionDateTimeRangePattern(dateTimeFormat, x, y). + + PartitionDateTimeRangePattern ( dateTimeFormat, x, y ) + + 1. Let x be TimeClip(x). + 2. If x is NaN, throw a RangeError exception. + 3. Let y be TimeClip(y). + 4. If y is NaN, throw a RangeError exception. + +features: [Intl.DateTimeFormat-formatRange] +---*/ + +var dtf = new Intl.DateTimeFormat(); + +var date = new Date(); + +assert.throws(RangeError, function() { + dtf.formatRange(NaN, date); +}, "NaN/date"); + +assert.throws(RangeError, function() { + dtf.formatRange(date, NaN); +}, "date/NaN"); + +assert.throws(RangeError, function() { + dtf.formatRange(NaN, NaN); +}, "NaN/NaN"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-same-returns-single-date.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-same-returns-single-date.js new file mode 100644 index 0000000000..684130fc7c --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-same-returns-single-date.js @@ -0,0 +1,64 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2021 Google Inc. All rights reserved. +// Copyright 2021 Apple Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimerangepattern +description: > + When startDate is equal to endDate, the output should be a string equal + to the output of Intl.DateTimeFormat.prototype.format. +info: | + Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate ) + + 4. Let x be ? ToNumber(startDate). + 5. Let y be ? ToNumber(endDate). + 6. Return ? FormatDateTimeRange(dtf, x, y). + + PartitionDateTimeRangePattern ( dateTimeFormat, x, y ) + + 13. If dateFieldsPracticallyEqual is true, then + a. Let pattern be dateTimeFormat.[[Pattern]]. + b. Let patternParts be PartitionPattern(pattern). + c. Let result be ? FormatDateTimePattern(dateTimeFormat, patternParts, tm1). + d. For each r in result do + i. Set r.[[Source]] to "shared". + e. Return result. + +features: [Intl.DateTimeFormat-formatRange] +locale: [en-US] +---*/ + +{ + const date = new Date(2019, 7, 10, 1, 2, 3, 234); + + let dtf = new Intl.DateTimeFormat("en", { year: "numeric", month: "short", day: "numeric" }); + assert.sameValue(dtf.formatRange(date, date), dtf.format(date), "same output with date options"); + + dtf = new Intl.DateTimeFormat("en", { minute: "numeric", second: "numeric" }); + assert.sameValue(dtf.formatRange(date, date), dtf.format(date), "same output with time options"); + + dtf = new Intl.DateTimeFormat("en", { month: "short", day: "numeric", minute: "numeric" }); + assert.sameValue(dtf.formatRange(date, date), dtf.format(date), "same output with date-time options"); + + dtf = new Intl.DateTimeFormat("en", { dateStyle: "long", timeStyle: "short" }); + assert.sameValue(dtf.formatRange(date, date), dtf.format(date), "same output with dateStyle/timeStyle"); +} +{ + const date1 = new Date(2019, 7, 10, 1, 2, 3, 234); + const date2 = new Date(2019, 7, 10, 1, 2, 3, 235); + + let dtf = new Intl.DateTimeFormat("en", { year: "numeric", month: "short", day: "numeric" }); + assert.sameValue(dtf.formatRange(date1, date2), dtf.format(date1), "same output with date options"); + + dtf = new Intl.DateTimeFormat("en", { minute: "numeric", second: "numeric" }); + assert.sameValue(dtf.formatRange(date1, date2), dtf.format(date1), "same output with time options"); + + dtf = new Intl.DateTimeFormat("en", { month: "short", day: "numeric", minute: "numeric" }); + assert.sameValue(dtf.formatRange(date1, date2), dtf.format(date1), "same output with date-time options"); + + dtf = new Intl.DateTimeFormat("en", { dateStyle: "long", timeStyle: "short" }); + assert.sameValue(dtf.formatRange(date1, date2), dtf.format(date1), "same output with dateStyle/timeStyle"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-undefined-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-undefined-throws.js new file mode 100644 index 0000000000..69946151c5 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-undefined-throws.js @@ -0,0 +1,45 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Google, Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Throws a TypeError if startDate or endDate is undefined. +info: | + Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate ) + + 1. Let dtf be this value. + 2. If Type(dtf) is not Object, throw a TypeError exception. + 3. If dtf does not have an [[InitializedDateTimeFormat]] internal slot, throw a TypeError exception. + 4. If startDate is undefined or endDate is undefined, throw a TypeError exception. + 5. Let x be ? ToNumber(startDate). + 6. Let y be ? ToNumber(endDate). + +features: [Intl.DateTimeFormat-formatRange] +---*/ + +var dtf = new Intl.DateTimeFormat(); + +assert.throws(TypeError, function() { + dtf.formatRange(); // Not possible to poison this one +}, "no args"); + +var poison = { valueOf() { throw new Test262Error(); } }; + +assert.throws(TypeError, function() { + dtf.formatRange(undefined, poison); +}, "date/undefined"); + +assert.throws(TypeError, function() { + dtf.formatRange(poison, undefined); +}, "undefined/date"); + +assert.throws(TypeError, function() { + dtf.formatRange(poison); +}, "only one arg"); + +assert.throws(TypeError, function() { + dtf.formatRange(undefined, undefined); +}, "undefined/undefined"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-x-greater-than-y-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-x-greater-than-y-throws.js new file mode 100644 index 0000000000..52a44597a9 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/date-x-greater-than-y-throws.js @@ -0,0 +1,40 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Google, Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Throws a RangeError if date x is greater than y. +info: | + Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate ) + + 4. Let x be ? ToNumber(startDate). + 5. Let y be ? ToNumber(endDate). + 6. Return ? FormatDateTimeRange(dtf, x, y). + + PartitionDateTimeRangePattern ( dateTimeFormat, x, y ) + + 1. Let x be TimeClip(x). + 2. If x is NaN, throw a RangeError exception. + 3. Let y be TimeClip(y). + 4. If y is NaN, throw a RangeError exception. + 5. If x is greater than y, throw a RangeError exception. + +features: [Intl.DateTimeFormat-formatRange] +---*/ + +var dtf = new Intl.DateTimeFormat(); + +var x = new Date(); +var y = new Date(); +x.setDate(y.getDate() + 1); + +assert.throws(RangeError, function() { + dtf.formatRange(x, y); +}, "x > y"); + +assert.sameValue("string", typeof dtf.formatRange(x, x)); +assert.sameValue("string", typeof dtf.formatRange(y, y)); +assert.sameValue("string", typeof dtf.formatRange(y, x)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/en-US.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/en-US.js new file mode 100644 index 0000000000..7fc01e452a --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/en-US.js @@ -0,0 +1,39 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright (C) 2019 the V8 project authors, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimerangepattern +description: Basic tests for the en-US output of formatRange() +info: | + Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate ) + + 8. Return ? FormatDateTimeRange(dtf, x, y). +locale: [en-US] +features: [Intl.DateTimeFormat-formatRange] +---*/ + +const date1 = new Date("2019-01-03T00:00:00"); +const date2 = new Date("2019-01-05T00:00:00"); +const date3 = new Date("2019-03-04T00:00:00"); +const date4 = new Date("2020-03-04T00:00:00"); + +let dtf = new Intl.DateTimeFormat("en-US"); +assert.sameValue(dtf.formatRange(date1, date1), "1/3/2019"); +assert.sameValue(dtf.formatRange(date1, date2), "1/3/2019 – 1/5/2019"); +assert.sameValue(dtf.formatRange(date1, date3), "1/3/2019 – 3/4/2019"); +assert.sameValue(dtf.formatRange(date1, date4), "1/3/2019 – 3/4/2020"); +assert.sameValue(dtf.formatRange(date2, date3), "1/5/2019 – 3/4/2019"); +assert.sameValue(dtf.formatRange(date2, date4), "1/5/2019 – 3/4/2020"); +assert.sameValue(dtf.formatRange(date3, date4), "3/4/2019 – 3/4/2020"); + +dtf = new Intl.DateTimeFormat("en-US", {year: "numeric", month: "short", day: "numeric"}); +assert.sameValue(dtf.formatRange(date1, date1), "Jan 3, 2019"); +assert.sameValue(dtf.formatRange(date1, date2), "Jan 3 – 5, 2019"); +assert.sameValue(dtf.formatRange(date1, date3), "Jan 3 – Mar 4, 2019"); +assert.sameValue(dtf.formatRange(date1, date4), "Jan 3, 2019 – Mar 4, 2020"); +assert.sameValue(dtf.formatRange(date2, date3), "Jan 5 – Mar 4, 2019"); +assert.sameValue(dtf.formatRange(date2, date4), "Jan 5, 2019 – Mar 4, 2020"); +assert.sameValue(dtf.formatRange(date3, date4), "Mar 4, 2019 – Mar 4, 2020"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/fractionalSecondDigits.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/fractionalSecondDigits.js new file mode 100644 index 0000000000..89b83aeacb --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/fractionalSecondDigits.js @@ -0,0 +1,36 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks basic handling of fractionalSecondDigits. +features: [Intl.DateTimeFormat-fractionalSecondDigits, Intl.DateTimeFormat-formatRange] +locale: [en-US] +---*/ + +const d1 = new Date(2019, 7, 10, 1, 2, 3, 234); +const d2 = new Date(2019, 7, 10, 1, 2, 3, 567); +const d3 = new Date(2019, 7, 10, 1, 2, 13, 987); + +let dtf = new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: undefined}); +assert.sameValue(dtf.formatRange(d1, d2), "02:03", "no fractionalSecondDigits"); +assert.sameValue(dtf.formatRange(d1, d3), "02:03 – 02:13", "no fractionalSecondDigits"); + +dtf = new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 1}); +assert.sameValue(dtf.formatRange(d1, d2), "02:03.2 – 02:03.5", "1 fractionalSecondDigits round down"); +assert.sameValue(dtf.formatRange(d1, d3), "02:03.2 – 02:13.9", "1 fractionalSecondDigits round down"); + +dtf = new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 2}); +assert.sameValue(dtf.formatRange(d1, d2), "02:03.23 – 02:03.56", "2 fractionalSecondDigits round down"); +assert.sameValue(dtf.formatRange(d1, d3), "02:03.23 – 02:13.98", "2 fractionalSecondDigits round down"); + +dtf = new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 3}); +assert.sameValue(dtf.formatRange(d1, d2), "02:03.234 – 02:03.567", "3 fractionalSecondDigits round down"); +assert.sameValue(dtf.formatRange(d1, d3), "02:03.234 – 02:13.987", "3 fractionalSecondDigits round down"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/length.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/length.js new file mode 100644 index 0000000000..f2f1997596 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/length.js @@ -0,0 +1,17 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Google, Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Intl.DateTimeFormat.prototype.formatRange.length. +includes: [propertyHelper.js] +features: [Intl.DateTimeFormat-formatRange] +---*/ +verifyProperty(Intl.DateTimeFormat.prototype.formatRange, 'length', { + value: 2, + enumerable: false, + writable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/name.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/name.js new file mode 100644 index 0000000000..1ef3d5199a --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/name.js @@ -0,0 +1,17 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Google, Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Intl.DateTimeFormat.prototype.formatRange.name value and descriptor. +includes: [propertyHelper.js] +features: [Intl.DateTimeFormat-formatRange] +---*/ +verifyProperty(Intl.DateTimeFormat.prototype.formatRange, 'name', { + value: 'formatRange', + enumerable: false, + writable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/prop-desc.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/prop-desc.js new file mode 100644 index 0000000000..c628b1866b --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/prop-desc.js @@ -0,0 +1,24 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2016 Mozilla Corporation. All rights reserved. +// Copyright 2019 Igalia S.L. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +description: Property type and descriptor. +includes: [propertyHelper.js] +features: [Intl.DateTimeFormat-formatRange] +---*/ + +assert.sameValue( + typeof Intl.DateTimeFormat.prototype.formatRange, + 'function', + '`typeof Intl.DateTimeFormat.prototype.formatRange` is `function`' +); + +verifyProperty(Intl.DateTimeFormat.prototype, 'formatRange', { + enumerable: false, + writable: true, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/shell.js new file mode 100644 index 0000000000..a96394ce86 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/shell.js @@ -0,0 +1,50 @@ +// GENERATED, DO NOT EDIT +// file: dateConstants.js +// Copyright (C) 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + Collection of date-centric values +defines: + - date_1899_end + - date_1900_start + - date_1969_end + - date_1970_start + - date_1999_end + - date_2000_start + - date_2099_end + - date_2100_start + - start_of_time + - end_of_time +---*/ + +var date_1899_end = -2208988800001; +var date_1900_start = -2208988800000; +var date_1969_end = -1; +var date_1970_start = 0; +var date_1999_end = 946684799999; +var date_2000_start = 946684800000; +var date_2099_end = 4102444799999; +var date_2100_start = 4102444800000; + +var start_of_time = -8.64e15; +var end_of_time = 8.64e15; + +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +---*/ + +function isConstructor(f) { + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/this-bad-object.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/this-bad-object.js new file mode 100644 index 0000000000..f3bf16339f --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/this-bad-object.js @@ -0,0 +1,29 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Igalia, S.L. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +description: > + Throws a TypeError if this is not a DateTimeFormat object +features: [Intl.DateTimeFormat-formatRange] +---*/ + +const formatRange = Intl.DateTimeFormat.prototype.formatRange; + +assert.throws(TypeError, function() { + formatRange.call({}); +}, "{}"); + +assert.throws(TypeError, function() { + formatRange.call(new Date()); +}, "new Date()"); + +assert.throws(TypeError, function() { + formatRange.call(Intl.DateTimeFormat); +}, "Intl.DateTimeFormat"); + +assert.throws(TypeError, function() { + formatRange.call(Intl.DateTimeFormat.prototype); +}, "Intl.DateTimeFormat.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/this-is-not-object-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/this-is-not-object-throws.js new file mode 100644 index 0000000000..8bd0016e2f --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRange/this-is-not-object-throws.js @@ -0,0 +1,50 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Google, Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Throws a TypeError if this is not Object. +info: | + Intl.DateTimeFormat.prototype.formatRange ( startDate , endDate ) + + 1. Let dtf be this value. + 2. If Type(dtf) is not Object, throw a TypeError exception. + +features: [Intl.DateTimeFormat-formatRange, Symbol] +---*/ + +let formatRange = Intl.DateTimeFormat.prototype.formatRange; +let d1 = new Date("1997-08-22T00:00"); +let d2 = new Date("1999-06-26T00:00"); + +assert.throws(TypeError, function() { + formatRange.call(undefined, d1, d2); +}, "undefined"); + +assert.throws(TypeError, function() { + formatRange.call(null, d1, d2); +}, "null"); + +assert.throws(TypeError, function() { + formatRange.call(42, d1, d2); +}, "number"); + +assert.throws(TypeError, function() { + formatRange.call("foo", d1, d2); +}, "string"); + +assert.throws(TypeError, function() { + formatRange.call(false, d1, d2); +}, "false"); + +assert.throws(TypeError, function() { + formatRange.call(true, d1, d2); +}, "true"); + +var s = Symbol('3'); +assert.throws(TypeError, function() { + formatRange.call(s, d1, d2); +}, "symbol"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-date-string.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-date-string.js new file mode 100644 index 0000000000..b61c8219c6 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-date-string.js @@ -0,0 +1,42 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright (C) 2017 André Bargull. All rights reserved. +// Copyright (C) 2019 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimerangepattern +description: > + The Date constructor is not called to convert the input value. +info: | + Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate ) + + 5. Let x be ? ToNumber(startDate). + 6. Let y be ? ToNumber(endDate). + 8. Return ? FormatDateTimeRange(dtf, x, y). + + PartitionDateTimeRangePattern ( dateTimeFormat, x, y ) + + 1. Let x be TimeClip(x). + 2. If x is NaN, throw a RangeError exception. + 3. Let y be TimeClip(y). + 4. If y is NaN, throw a RangeError exception. +features: [Intl.DateTimeFormat-formatRange] +---*/ + +const dtf = new Intl.DateTimeFormat(); +const dateTimeString = "2017-11-10T14:09:00.000Z"; +const date = new Date(dateTimeString); +// |dateTimeString| is valid ISO-8601 style date/time string. +assert.notSameValue(date, NaN); + +// ToNumber() will try to parse the string as an integer and yield NaN, rather +// than attempting to parse it like the Date constructor would. +assert.throws(RangeError, function() { + dtf.formatRangeToParts(dateTimeString, date); +}); + +assert.throws(RangeError, function() { + dtf.formatRangeToParts(date, dateTimeString); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-near-time-boundaries.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-near-time-boundaries.js new file mode 100644 index 0000000000..1ce7ce1e7c --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-near-time-boundaries.js @@ -0,0 +1,50 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright (C) 2017 André Bargull. All rights reserved. +// Copyright (C) 2019 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimerangepattern +description: > + TimeClip is applied when calling Intl.DateTimeFormat.prototype.formatRangeToParts. +info: | + PartitionDateTimeRangePattern ( dateTimeFormat, x, y ) + + 1. Let x be TimeClip(x). + 2. If x is NaN, throw a RangeError exception. + 3. Let y be TimeClip(y). + 4. If y is NaN, throw a RangeError exception. + + TimeClip ( time ) + ... + 2. If abs(time) > 8.64 × 10^15, return NaN. + ... + +includes: [dateConstants.js] +features: [Intl.DateTimeFormat-formatRange] +---*/ + +const dtf = new Intl.DateTimeFormat(); +const date = Date.now(); + +// Test values near the start of the ECMAScript time range. +assert.throws(RangeError, function() { + dtf.formatRangeToParts(start_of_time - 1, date); +}); +assert.throws(RangeError, function() { + dtf.formatRangeToParts(date, start_of_time - 1); +}); +assert.sameValue(typeof dtf.formatRangeToParts(start_of_time, date), "object"); +assert.sameValue(typeof dtf.formatRangeToParts(start_of_time + 1, date), "object"); + +// Test values near the end of the ECMAScript time range. +assert.sameValue(typeof dtf.formatRangeToParts(date, end_of_time - 1), "object"); +assert.sameValue(typeof dtf.formatRangeToParts(date, end_of_time), "object"); +assert.throws(RangeError, function() { + dtf.formatRangeToParts(end_of_time + 1, date); +}); +assert.throws(RangeError, function() { + dtf.formatRangeToParts(date, end_of_time + 1); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-to-integer.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-to-integer.js new file mode 100644 index 0000000000..eb36b29eac --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-to-integer.js @@ -0,0 +1,57 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright (C) 2017 André Bargull. All rights reserved. +// Copyright (C) 2019 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimerangepattern +description: > + TimeClip applies ToInteger on its input value. +info: | + Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate ) + + 5. Let x be ? ToNumber(startDate). + 6. Let y be ? ToNumber(endDate). + + TimeClip ( time ) + ... + 3. Let clippedTime be ! ToInteger(time). + 4. If clippedTime is -0, set clippedTime to +0. + 5. Return clippedTime. +features: [Intl.DateTimeFormat-formatRange] +---*/ + +function* zip(a, b) { + assert.sameValue(a.length, b.length); + for (let i = 0; i < a.length; ++i) { + yield [i, a[i], b[i]]; + } +} + +function compare(actual, expected, message) { + for (const [i, actualEntry, expectedEntry] of zip(actual, expected)) { + assert.sameValue(actualEntry.type, expectedEntry.type, `${message}: type for entry ${i}`); + assert.sameValue(actualEntry.value, expectedEntry.value, `${message}: value for entry ${i}`); + assert.sameValue(actualEntry.source, expectedEntry.source, `${message}: source for entry ${i}`); + } +} + +// Switch to a time format instead of using DateTimeFormat's default date-only format. +const dtf = new Intl.DateTimeFormat(undefined, { + hour: "numeric", minute: "numeric", second: "numeric" +}); +const date = Date.now(); +const expected = dtf.formatRangeToParts(0, date); + +compare(dtf.formatRangeToParts(-0.9, date), expected, "formatRangeToParts(-0.9)"); +compare(dtf.formatRangeToParts(-0.5, date), expected, "formatRangeToParts(-0.5)"); +compare(dtf.formatRangeToParts(-0.1, date), expected, "formatRangeToParts(-0.1)"); +compare(dtf.formatRangeToParts(-Number.MIN_VALUE, date), expected, "formatRangeToParts(-Number.MIN_VALUE)"); +compare(dtf.formatRangeToParts(-0, date), expected, "formatRangeToParts(-0)"); +compare(dtf.formatRangeToParts(+0, date), expected, "formatRangeToParts(+0)"); +compare(dtf.formatRangeToParts(Number.MIN_VALUE, date), expected, "formatRangeToParts(Number.MIN_VALUE)"); +compare(dtf.formatRangeToParts(0.1, date), expected, "formatRangeToParts(0.1)"); +compare(dtf.formatRangeToParts(0.5, date), expected, "formatRangeToParts(0.5)"); +compare(dtf.formatRangeToParts(0.9, date), expected, "formatRangeToParts(0.9)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-tonumber-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-tonumber-throws.js new file mode 100644 index 0000000000..287c853cc1 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/argument-tonumber-throws.js @@ -0,0 +1,57 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Igalia S.L. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +description: > + Return abrupt completions from ToNumber(date) +info: | + Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate ) + + 5. Let x be ? ToNumber(startDate). + 6. Let y be ? ToNumber(endDate). +features: [Symbol,Intl.DateTimeFormat-formatRange] +---*/ + +const date = Date.now(); + +const objectValueOf = { + valueOf: function() { + throw new Test262Error(); + } +}; + +const objectToString = { + toString: function() { + throw new Test262Error(); + } +}; + +const dtf = new Intl.DateTimeFormat(["pt-BR"]); + +assert.throws(Test262Error, function() { + dtf.formatRangeToParts(objectValueOf, date); +}, "valueOf start"); + +assert.throws(Test262Error, function() { + dtf.formatRangeToParts(date, objectValueOf); +}, "valueOf end"); + +assert.throws(Test262Error, function() { + dtf.formatRangeToParts(objectToString, date); +}, "toString start"); + +assert.throws(Test262Error, function() { + dtf.formatRangeToParts(date, objectToString); +}, "toString end"); + +const s = Symbol('1'); +assert.throws(TypeError, function() { + dtf.formatRangeToParts(s, date); +}, "symbol start"); + +assert.throws(TypeError, function() { + dtf.formatRangeToParts(date, s); +}, "symbol end"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/browser.js diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/builtin.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/builtin.js new file mode 100644 index 0000000000..6807ddf6b0 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/builtin.js @@ -0,0 +1,33 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2012 Mozilla Corporation. All rights reserved. +// Copyright 2019 Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-ecmascript-standard-built-in-objects +description: > + Tests that the Intl.DateTimeFormat.prototype.formatRangeToParts function meets the + requirements for built-in objects defined by the ECMAScript Language + Specification. +includes: [isConstructor.js] +features: [Reflect.construct,Intl.DateTimeFormat-formatRange] +---*/ + +const formatRangeToParts = Intl.DateTimeFormat.prototype.formatRangeToParts; + +assert.sameValue(Object.prototype.toString.call(formatRangeToParts), "[object Function]", + "The [[Class]] internal property of a built-in function must be " + + "\"Function\"."); + +assert(Object.isExtensible(formatRangeToParts), + "Built-in objects must be extensible."); + +assert.sameValue(Object.getPrototypeOf(formatRangeToParts), Function.prototype); + +assert.sameValue(formatRangeToParts.hasOwnProperty("prototype"), false, + "Built-in functions that aren't constructors must not have a prototype property."); + +assert.sameValue(isConstructor(formatRangeToParts), false, + "Built-in functions don't implement [[Construct]] unless explicitly specified."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-is-infinity-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-is-infinity-throws.js new file mode 100644 index 0000000000..d9d9b27c9d --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-is-infinity-throws.js @@ -0,0 +1,72 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Google, Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Throws a RangeError if date arg is cast to an Infinity value +info: | + Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate ) + + 1. Let dtf be this value. + 2. If Type(dtf) is not Object, throw a TypeError exception. + 3. If dtf does not have an [[InitializedDateTimeFormat]] internal slot, throw a TypeError exception. + 4. If startDate is undefined or endDate is undefined, throw a RangeError exception. + 5. Let x be ? ToNumber(startDate). + 6. Let y be ? ToNumber(endDate). + 7. If x is greater than y, throw a RangeError exception. + 8. Return ? FormatDateTimeRangeToParts(dtf, x, y). + + FormatDateTimeRangeToParts ( dateTimeFormat, x, y ) + + 1. Let parts be ? PartitionDateTimeRangePattern(dateTimeFormat, x, y). + + PartitionDateTimeRangePattern ( dateTimeFormat, x, y ) + 1. Let x be TimeClip(x). + 2. If x is NaN, throw a RangeError exception. + 3. Let y be TimeClip(y). + 4. If y is NaN, throw a RangeError exception. + + TimeClip ( time ) + 1. If time is not finite, return NaN. + +features: [Intl.DateTimeFormat-formatRange] +---*/ + +var dtf = new Intl.DateTimeFormat(); + +var date = new Date(); + +assert.throws(RangeError, function() { + dtf.formatRangeToParts(Infinity, date); +}, "+Infinity/date"); + +assert.throws(RangeError, function() { + dtf.formatRangeToParts(-Infinity, date); +}, "-Infinity/date"); + +assert.throws(RangeError, function() { + dtf.formatRangeToParts(date, Infinity); +}, "date/+Infinity"); + +assert.throws(RangeError, function() { + dtf.formatRangeToParts(date, -Infinity); +}, "date/-Infinity"); + +assert.throws(RangeError, function() { + dtf.formatRangeToParts(Infinity, Infinity); +}, "+Infinity/+Infinity"); + +assert.throws(RangeError, function() { + dtf.formatRangeToParts(-Infinity, -Infinity); +}, "-Infinity/-Infinity"); + +assert.throws(RangeError, function() { + dtf.formatRangeToParts(Infinity, -Infinity); +}, "+Infinity/-Infinity"); + +assert.throws(RangeError, function() { + dtf.formatRangeToParts(-Infinity, Infinity); +}, "-Infinity/+Infinity"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-is-nan-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-is-nan-throws.js new file mode 100644 index 0000000000..22d3f5af15 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-is-nan-throws.js @@ -0,0 +1,50 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Google, Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Throws a RangeError if date arg is cast to Nan +info: | + Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate ) + + 1. Let dtf be this value. + 2. If Type(dtf) is not Object, throw a TypeError exception. + 3. If dtf does not have an [[InitializedDateTimeFormat]] internal slot, throw a TypeError exception. + 4. If startDate is undefined or endDate is undefined, throw a RangeError exception. + 5. Let x be ? ToNumber(startDate). + 6. Let y be ? ToNumber(endDate). + 7. If x is greater than y, throw a RangeError exception. + 8. Return ? FormatDateTimeRangeToParts(dtf, x, y). + + FormatDateTimeRangeToParts ( dateTimeFormat, x, y ) + + 1. Let parts be ? PartitionDateTimeRangePattern(dateTimeFormat, x, y). + + PartitionDateTimeRangePattern ( dateTimeFormat, x, y ) + + 1. Let x be TimeClip(x). + 2. If x is NaN, throw a RangeError exception. + 3. Let y be TimeClip(y). + 4. If y is NaN, throw a RangeError exception. + +features: [Intl.DateTimeFormat-formatRange] +---*/ + +var dtf = new Intl.DateTimeFormat(); + +var date = new Date(); + +assert.throws(RangeError, function() { + dtf.formatRangeToParts(NaN, date); +}, "NaN/date"); + +assert.throws(RangeError, function() { + dtf.formatRangeToParts(date, NaN); +}, "date/NaN"); + +assert.throws(RangeError, function() { + dtf.formatRangeToParts(NaN, NaN); +}, "NaN/NaN"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-same-returns-single-date.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-same-returns-single-date.js new file mode 100644 index 0000000000..d12c7bb9a8 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-same-returns-single-date.js @@ -0,0 +1,79 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2021 Google Inc. All rights reserved. +// Copyright 2021 Apple Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimerangepattern +description: > + When startDate is equal to endDate, the output should be an Array of objects with the + same value for the `type` and `value` fields as in the Array returned by + Intl.DateTimeFormat.prototype.formatToParts. +info: | + Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate ) + + 4. Let x be ? ToNumber(startDate). + 5. Let y be ? ToNumber(endDate). + 6. Return ? FormatDateTimeRange(dtf, x, y). + + PartitionDateTimeRangePattern ( dateTimeFormat, x, y ) + + 13. If dateFieldsPracticallyEqual is true, then + a. Let pattern be dateTimeFormat.[[Pattern]]. + b. Let patternParts be PartitionPattern(pattern). + c. Let result be ? FormatDateTimePattern(dateTimeFormat, patternParts, tm1). + d. For each r in result do + i. Set r.[[Source]] to "shared". + e. Return result. + +features: [Intl.DateTimeFormat-formatRange] +locale: [en-US] +---*/ + +function* zip(a, b) { + assert.sameValue(a.length, b.length); + for (let i = 0; i < a.length; ++i) { + yield [i, a[i], b[i]]; + } +} + +function compare(actual, expected) { + for (const [i, actualEntry, expectedEntry] of zip(actual, expected)) { + assert.sameValue(actualEntry.type, expectedEntry.type, `type for entry ${i}`); + assert.sameValue(actualEntry.value, expectedEntry.value, `value for entry ${i}`); + } +} + +{ + const date = new Date(2019, 7, 10, 1, 2, 3, 234); + + let dtf = new Intl.DateTimeFormat("en", { year: "numeric", month: "short", day: "numeric" }); + compare(dtf.formatRangeToParts(date, date), dtf.formatToParts(date), "same output with date options"); + + dtf = new Intl.DateTimeFormat("en", { minute: "numeric", second: "numeric" }); + compare(dtf.formatRangeToParts(date, date), dtf.formatToParts(date), "same output with time options"); + + dtf = new Intl.DateTimeFormat("en", { month: "short", day: "numeric", minute: "numeric" }); + compare(dtf.formatRangeToParts(date, date), dtf.formatToParts(date), "same output with date-time options"); + + dtf = new Intl.DateTimeFormat("en", { dateStyle: "long", timeStyle: "short" }); + compare(dtf.formatRangeToParts(date, date), dtf.formatToParts(date), "same output with dateStyle/timeStyle"); +} +{ + const date1 = new Date(2019, 7, 10, 1, 2, 3, 234); + const date2 = new Date(2019, 7, 10, 1, 2, 3, 235); + + let dtf = new Intl.DateTimeFormat("en", { year: "numeric", month: "short", day: "numeric" }); + compare(dtf.formatRangeToParts(date1, date2), dtf.formatToParts(date1), "same output with date options"); + + dtf = new Intl.DateTimeFormat("en", { minute: "numeric", second: "numeric" }); + compare(dtf.formatRangeToParts(date1, date2), dtf.formatToParts(date1), "same output with time options"); + + dtf = new Intl.DateTimeFormat("en", { month: "short", day: "numeric", minute: "numeric" }); + compare(dtf.formatRangeToParts(date1, date2), dtf.formatToParts(date1), "same output with date-time options"); + + dtf = new Intl.DateTimeFormat("en", { dateStyle: "long", timeStyle: "short" }); + compare(dtf.formatRangeToParts(date1, date2), dtf.formatToParts(date1), "same output with dateStyle/timeStyle"); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-undefined-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-undefined-throws.js new file mode 100644 index 0000000000..7ac2c44bd1 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-undefined-throws.js @@ -0,0 +1,44 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Google, Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Throws a TypeError if startDate or endDate are undefined. +info: | + Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate ) + + 1. Let dtf be this value. + 2. If Type(dtf) is not Object, throw a TypeError exception. + 3. If dtf does not have an [[InitializedDateTimeFormat]] internal slot, throw a TypeError exception. + 4. If startDate is undefined or endDate is undefined, throw a TypeError exception. + 5. Let x be ? ToNumber(startDate). + 6. Let y be ? ToNumber(endDate). + +features: [Intl.DateTimeFormat-formatRange] +---*/ +var dtf = new Intl.DateTimeFormat(); + +assert.throws(TypeError, function() { + dtf.formatRangeToParts(); // Not possible to poison this one +}, "no args"); + +var poison = { valueOf() { throw new Test262Error(); } }; + +assert.throws(TypeError, function() { + dtf.formatRangeToParts(undefined, poison); +}, "date/undefined"); + +assert.throws(TypeError, function() { + dtf.formatRangeToParts(poison, undefined); +}, "undefined/date"); + +assert.throws(TypeError, function() { + dtf.formatRangeToParts(poison); +}, "only one arg"); + +assert.throws(TypeError, function() { + dtf.formatRangeToParts(undefined, undefined); +}, "undefined/undefined"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-x-greater-than-y-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-x-greater-than-y-throws.js new file mode 100644 index 0000000000..ab7032065f --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/date-x-greater-than-y-throws.js @@ -0,0 +1,39 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Google, Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Throws a RangeError if date x is greater than y. +info: | + Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate ) + + 4. Let x be ? ToNumber(startDate). + 5. Let y be ? ToNumber(endDate). + 6. Return ? FormatDateTimeRangeToParts(dtf, x, y). + + PartitionDateTimeRangePattern ( dateTimeFormat, x, y ) + + 1. Let x be TimeClip(x). + 2. If x is NaN, throw a RangeError exception. + 3. Let y be TimeClip(y). + 4. If y is NaN, throw a RangeError exception. + 5. If x is greater than y, throw a RangeError exception. + +features: [Intl.DateTimeFormat-formatRange] +---*/ + +var dtf = new Intl.DateTimeFormat(); + +var x = new Date(); +var y = new Date(); +x.setDate(y.getDate() + 1); + +assert.throws(RangeError, function() { + dtf.formatRangeToParts(x, y); +}, "x > y"); +assert.sameValue("object", typeof dtf.formatRangeToParts(x, x)); +assert.sameValue("object", typeof dtf.formatRangeToParts(y, y)); +assert.sameValue("object", typeof dtf.formatRangeToParts(y, x)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/en-US.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/en-US.js new file mode 100644 index 0000000000..563acdd47c --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/en-US.js @@ -0,0 +1,202 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright (C) 2019 the V8 project authors, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimerangepattern +description: Basic tests for the en-US output of formatRangeToParts() +info: | + Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate ) + + 8. Return ? FormatDateTimeRange(dtf, x, y). +locale: [en-US] +features: [Intl.DateTimeFormat-formatRange] +---*/ + +function* zip(a, b) { + assert.sameValue(a.length, b.length); + for (let i = 0; i < a.length; ++i) { + yield [i, a[i], b[i]]; + } +} + +function compare(actual, expected) { + for (const [i, actualEntry, expectedEntry] of zip(actual, expected)) { + assert.sameValue(actualEntry.type, expectedEntry.type, `type for entry ${i}`); + assert.sameValue(actualEntry.value, expectedEntry.value, `value for entry ${i}`); + assert.sameValue(actualEntry.source, expectedEntry.source, `source for entry ${i}`); + } +} + +const date1 = new Date("2019-01-03T00:00:00"); +const date2 = new Date("2019-01-05T00:00:00"); +const date3 = new Date("2019-03-04T00:00:00"); +const date4 = new Date("2020-03-04T00:00:00"); + +let dtf = new Intl.DateTimeFormat("en-US"); +compare(dtf.formatRangeToParts(date1, date1), [ + { type: "month", value: "1", source: "shared" }, + { type: "literal", value: "/", source: "shared" }, + { type: "day", value: "3", source: "shared" }, + { type: "literal", value: "/", source: "shared" }, + { type: "year", value: "2019", source: "shared" }, +]); +compare(dtf.formatRangeToParts(date1, date2), [ + { type: "month", value: "1", source: "startRange" }, + { type: "literal", value: "/", source: "startRange" }, + { type: "day", value: "3", source: "startRange" }, + { type: "literal", value: "/", source: "startRange" }, + { type: "year", value: "2019", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "month", value: "1", source: "endRange" }, + { type: "literal", value: "/", source: "endRange" }, + { type: "day", value: "5", source: "endRange" }, + { type: "literal", value: "/", source: "endRange" }, + { type: "year", value: "2019", source: "endRange" }, +]); +compare(dtf.formatRangeToParts(date1, date3), [ + { type: "month", value: "1", source: "startRange" }, + { type: "literal", value: "/", source: "startRange" }, + { type: "day", value: "3", source: "startRange" }, + { type: "literal", value: "/", source: "startRange" }, + { type: "year", value: "2019", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "month", value: "3", source: "endRange" }, + { type: "literal", value: "/", source: "endRange" }, + { type: "day", value: "4", source: "endRange" }, + { type: "literal", value: "/", source: "endRange" }, + { type: "year", value: "2019", source: "endRange" }, +]); +compare(dtf.formatRangeToParts(date1, date4), [ + { type: "month", value: "1", source: "startRange" }, + { type: "literal", value: "/", source: "startRange" }, + { type: "day", value: "3", source: "startRange" }, + { type: "literal", value: "/", source: "startRange" }, + { type: "year", value: "2019", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "month", value: "3", source: "endRange" }, + { type: "literal", value: "/", source: "endRange" }, + { type: "day", value: "4", source: "endRange" }, + { type: "literal", value: "/", source: "endRange" }, + { type: "year", value: "2020", source: "endRange" }, +]); +compare(dtf.formatRangeToParts(date2, date3), [ + { type: "month", value: "1", source: "startRange" }, + { type: "literal", value: "/", source: "startRange" }, + { type: "day", value: "5", source: "startRange" }, + { type: "literal", value: "/", source: "startRange" }, + { type: "year", value: "2019", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "month", value: "3", source: "endRange" }, + { type: "literal", value: "/", source: "endRange" }, + { type: "day", value: "4", source: "endRange" }, + { type: "literal", value: "/", source: "endRange" }, + { type: "year", value: "2019", source: "endRange" }, +]); +compare(dtf.formatRangeToParts(date2, date4), [ + { type: "month", value: "1", source: "startRange" }, + { type: "literal", value: "/", source: "startRange" }, + { type: "day", value: "5", source: "startRange" }, + { type: "literal", value: "/", source: "startRange" }, + { type: "year", value: "2019", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "month", value: "3", source: "endRange" }, + { type: "literal", value: "/", source: "endRange" }, + { type: "day", value: "4", source: "endRange" }, + { type: "literal", value: "/", source: "endRange" }, + { type: "year", value: "2020", source: "endRange" }, +]); +compare(dtf.formatRangeToParts(date3, date4), [ + { type: "month", value: "3", source: "startRange" }, + { type: "literal", value: "/", source: "startRange" }, + { type: "day", value: "4", source: "startRange" }, + { type: "literal", value: "/", source: "startRange" }, + { type: "year", value: "2019", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "month", value: "3", source: "endRange" }, + { type: "literal", value: "/", source: "endRange" }, + { type: "day", value: "4", source: "endRange" }, + { type: "literal", value: "/", source: "endRange" }, + { type: "year", value: "2020", source: "endRange" }, +]); + +dtf = new Intl.DateTimeFormat("en-US", {year: "numeric", month: "short", day: "numeric"}); +compare(dtf.formatRangeToParts(date1, date1), [ + { type: "month", value: "Jan", source: "shared" }, + { type: "literal", value: " ", source: "shared" }, + { type: "day", value: "3", source: "shared" }, + { type: "literal", value: ", ", source: "shared" }, + { type: "year", value: "2019", source: "shared" }, +]); +compare(dtf.formatRangeToParts(date1, date2), [ + { type: "month", value: "Jan", source: "shared" }, + { type: "literal", value: " ", source: "shared" }, + { type: "day", value: "3", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "day", value: "5", source: "endRange" }, + { type: "literal", value: ", ", source: "shared" }, + { type: "year", value: "2019", source: "shared" }, +]); +compare(dtf.formatRangeToParts(date1, date3), [ + { type: "month", value: "Jan", source: "startRange" }, + { type: "literal", value: " ", source: "startRange" }, + { type: "day", value: "3", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "month", value: "Mar", source: "endRange" }, + { type: "literal", value: " ", source: "endRange" }, + { type: "day", value: "4", source: "endRange" }, + { type: "literal", value: ", ", source: "shared" }, + { type: "year", value: "2019", source: "shared" }, +]); +compare(dtf.formatRangeToParts(date1, date4), [ + { type: "month", value: "Jan", source: "startRange" }, + { type: "literal", value: " ", source: "startRange" }, + { type: "day", value: "3", source: "startRange" }, + { type: "literal", value: ", ", source: "startRange" }, + { type: "year", value: "2019", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "month", value: "Mar", source: "endRange" }, + { type: "literal", value: " ", source: "endRange" }, + { type: "day", value: "4", source: "endRange" }, + { type: "literal", value: ", ", source: "endRange" }, + { type: "year", value: "2020", source: "endRange" }, +]); +compare(dtf.formatRangeToParts(date2, date3), [ + { type: "month", value: "Jan", source: "startRange" }, + { type: "literal", value: " ", source: "startRange" }, + { type: "day", value: "5", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "month", value: "Mar", source: "endRange" }, + { type: "literal", value: " ", source: "endRange" }, + { type: "day", value: "4", source: "endRange" }, + { type: "literal", value: ", ", source: "shared" }, + { type: "year", value: "2019", source: "shared" }, +]); +compare(dtf.formatRangeToParts(date2, date4), [ + { type: "month", value: "Jan", source: "startRange" }, + { type: "literal", value: " ", source: "startRange" }, + { type: "day", value: "5", source: "startRange" }, + { type: "literal", value: ", ", source: "startRange" }, + { type: "year", value: "2019", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "month", value: "Mar", source: "endRange" }, + { type: "literal", value: " ", source: "endRange" }, + { type: "day", value: "4", source: "endRange" }, + { type: "literal", value: ", ", source: "endRange" }, + { type: "year", value: "2020", source: "endRange" }, +]); +compare(dtf.formatRangeToParts(date3, date4), [ + { type: "month", value: "Mar", source: "startRange" }, + { type: "literal", value: " ", source: "startRange" }, + { type: "day", value: "4", source: "startRange" }, + { type: "literal", value: ", ", source: "startRange" }, + { type: "year", value: "2019", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "month", value: "Mar", source: "endRange" }, + { type: "literal", value: " ", source: "endRange" }, + { type: "day", value: "4", source: "endRange" }, + { type: "literal", value: ", ", source: "endRange" }, + { type: "year", value: "2020", source: "endRange" }, +]); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/fractionalSecondDigits.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/fractionalSecondDigits.js new file mode 100644 index 0000000000..d6af440b80 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/fractionalSecondDigits.js @@ -0,0 +1,154 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2020 Google Inc, Igalia S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks basic handling of fractionalSecondDigits. +features: [Intl.DateTimeFormat-fractionalSecondDigits, Intl.DateTimeFormat-formatRange] +locale: [en-US] +---*/ + +function* zip(a, b) { + assert.sameValue(a.length, b.length); + for (let i = 0; i < a.length; ++i) { + yield [i, a[i], b[i]]; + } +} + +function compare(actual, expected) { + for (const [i, actualEntry, expectedEntry] of zip(actual, expected)) { + assert.sameValue(actualEntry.type, expectedEntry.type, `type for entry ${i}`); + assert.sameValue(actualEntry.value, expectedEntry.value, `value for entry ${i}`); + assert.sameValue(actualEntry.source, expectedEntry.source, `source for entry ${i}`); + } +} + +const d1 = new Date(2019, 7, 10, 1, 2, 3, 234); +const d2 = new Date(2019, 7, 10, 1, 2, 3, 567); +const d3 = new Date(2019, 7, 10, 1, 2, 13, 987); + +assert.throws(RangeError, () => { + new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 0}); + }, "fractionalSecondDigits 0 should throw RangeError for out of range"); + +assert.throws(RangeError, () => { + new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 4}); + }, "fractionalSecondDigits 4 should throw RangeError for out of range"); + +let dtf = new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: undefined}); + +compare(dtf.formatRangeToParts(d1, d2), [ + { type: "minute", value: "02", source: "shared" }, + { type: "literal", value: ":", source: "shared" }, + { type: "second", value: "03", source: "shared" } +]); + +compare(dtf.formatRangeToParts(d1, d3), [ + { type: "minute", value: "02", source: "startRange" }, + { type: "literal", value: ":", source: "startRange" }, + { type: "second", value: "03", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "minute", value: "02", source: "endRange" }, + { type: "literal", value: ":", source: "endRange" }, + { type: "second", value: "13", source: "endRange" } +]); + +dtf = new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 1}); + +compare(dtf.formatRangeToParts(d1, d2), [ + { type: "minute", value: "02", source: "startRange" }, + { type: "literal", value: ":", source: "startRange" }, + { type: "second", value: "03", source: "startRange" }, + { type: "literal", value: ".", source: "startRange" }, + { type: "fractionalSecond", value: "2", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "minute", value: "02", source: "endRange" }, + { type: "literal", value: ":", source: "endRange" }, + { type: "second", value: "03", source: "endRange" }, + { type: "literal", value: ".", source: "endRange" }, + { type: "fractionalSecond", value: "5", source: "endRange" } +]); + +compare(dtf.formatRangeToParts(d1, d3), [ + { type: "minute", value: "02", source: "startRange" }, + { type: "literal", value: ":", source: "startRange" }, + { type: "second", value: "03", source: "startRange" }, + { type: "literal", value: ".", source: "startRange" }, + { type: "fractionalSecond", value: "2", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "minute", value: "02", source: "endRange" }, + { type: "literal", value: ":", source: "endRange" }, + { type: "second", value: "13", source: "endRange" }, + { type: "literal", value: ".", source: "endRange" }, + { type: "fractionalSecond", value: "9", source: "endRange" } +]); + +dtf = new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 2}); + +compare(dtf.formatRangeToParts(d1, d2), [ + { type: "minute", value: "02", source: "startRange" }, + { type: "literal", value: ":", source: "startRange" }, + { type: "second", value: "03", source: "startRange" }, + { type: "literal", value: ".", source: "startRange" }, + { type: "fractionalSecond", value: "23", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "minute", value: "02", source: "endRange" }, + { type: "literal", value: ":", source: "endRange" }, + { type: "second", value: "03", source: "endRange" }, + { type: "literal", value: ".", source: "endRange" }, + { type: "fractionalSecond", value: "56", source: "endRange" } +]); + +compare(dtf.formatRangeToParts(d1, d3), [ + { type: "minute", value: "02", source: "startRange" }, + { type: "literal", value: ":", source: "startRange" }, + { type: "second", value: "03", source: "startRange" }, + { type: "literal", value: ".", source: "startRange" }, + { type: "fractionalSecond", value: "23", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "minute", value: "02", source: "endRange" }, + { type: "literal", value: ":", source: "endRange" }, + { type: "second", value: "13", source: "endRange" }, + { type: "literal", value: ".", source: "endRange" }, + { type: "fractionalSecond", value: "98", source: "endRange" } +]); + +dtf = new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 3}); + +compare(dtf.formatRangeToParts(d1, d2), [ + { type: "minute", value: "02", source: "startRange" }, + { type: "literal", value: ":", source: "startRange" }, + { type: "second", value: "03", source: "startRange" }, + { type: "literal", value: ".", source: "startRange" }, + { type: "fractionalSecond", value: "234", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "minute", value: "02", source: "endRange" }, + { type: "literal", value: ":", source: "endRange" }, + { type: "second", value: "03", source: "endRange" }, + { type: "literal", value: ".", source: "endRange" }, + { type: "fractionalSecond", value: "567", source: "endRange" } +]); + +compare(dtf.formatRangeToParts(d1, d3), [ + { type: "minute", value: "02", source: "startRange" }, + { type: "literal", value: ":", source: "startRange" }, + { type: "second", value: "03", source: "startRange" }, + { type: "literal", value: ".", source: "startRange" }, + { type: "fractionalSecond", value: "234", source: "startRange" }, + { type: "literal", value: " \u2013 ", source: "shared" }, + { type: "minute", value: "02", source: "endRange" }, + { type: "literal", value: ":", source: "endRange" }, + { type: "second", value: "13", source: "endRange" }, + { type: "literal", value: ".", source: "endRange" }, + { type: "fractionalSecond", value: "987", source: "endRange" } +]); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/length.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/length.js new file mode 100644 index 0000000000..d737e906ea --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/length.js @@ -0,0 +1,17 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Google, Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Intl.DateTimeFormat.prototype.formatRangeToParts.length. +includes: [propertyHelper.js] +features: [Intl.DateTimeFormat-formatRange] +---*/ +verifyProperty(Intl.DateTimeFormat.prototype.formatRangeToParts, 'length', { + value: 2, + enumerable: false, + writable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/name.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/name.js new file mode 100644 index 0000000000..a125c4bdda --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/name.js @@ -0,0 +1,17 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Google, Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Intl.DateTimeFormat.prototype.formatRangeToParts.name value and descriptor. +includes: [propertyHelper.js] +features: [Intl.DateTimeFormat-formatRange] +---*/ +verifyProperty(Intl.DateTimeFormat.prototype.formatRangeToParts, 'name', { + value: 'formatRangeToParts', + enumerable: false, + writable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/pattern-on-calendar.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/pattern-on-calendar.js new file mode 100644 index 0000000000..7161f44804 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/pattern-on-calendar.js @@ -0,0 +1,58 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Checks the DateTimeFormat choose different patterns based + on calendar. +features: [Intl.DateTimeFormat-formatRange] +locale: [en] +---*/ + +let calendars = [ + "buddhist", + "chinese", + "coptic", + "dangi", + "ethiopic", + "ethioaa", + "gregory", + "hebrew", + "indian", + "islamic", + "islamic-civil", + "islamic-rgsa", + "islamic-tbla", + "islamic-umalqura", + "japanese", + "persian", + "roc" +]; +let date1 = new Date(2017, 3, 12); +let date2 = new Date(); + +// serialize parts to a string by considering only the type and literal. +function serializeTypesAndLiteral(parts) { + let types = parts.map(part => { + if (part.type == "literal") { + return `${part.type}(${part.value})`; + } + return part.type; + }); + return types.join(":"); +} + +let df = new Intl.DateTimeFormat("en"); +let base = serializeTypesAndLiteral(df.formatRangeToParts(date1, date2)); + +const foundDifferentPattern = calendars.some(function(calendar) { + let cdf = new Intl.DateTimeFormat("en-u-ca-" + calendar); + return base != serializeTypesAndLiteral(cdf.formatRangeToParts(date1, date2)); +}); + +// Expect at least some calendar use different pattern. +assert.sameValue(foundDifferentPattern, true); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/prop-desc.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/prop-desc.js new file mode 100644 index 0000000000..c183abdc6c --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/prop-desc.js @@ -0,0 +1,24 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2016 Mozilla Corporation. All rights reserved. +// Copyright 2019 Igalia S.L. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +description: Property type and descriptor. +includes: [propertyHelper.js] +features: [Intl.DateTimeFormat-formatRange] +---*/ + +assert.sameValue( + typeof Intl.DateTimeFormat.prototype.formatRangeToParts, + 'function', + '`typeof Intl.DateTimeFormat.prototype.formatRangeToParts` is `function`' +); + +verifyProperty(Intl.DateTimeFormat.prototype, 'formatRangeToParts', { + enumerable: false, + writable: true, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/shell.js new file mode 100644 index 0000000000..a96394ce86 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/shell.js @@ -0,0 +1,50 @@ +// GENERATED, DO NOT EDIT +// file: dateConstants.js +// Copyright (C) 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + Collection of date-centric values +defines: + - date_1899_end + - date_1900_start + - date_1969_end + - date_1970_start + - date_1999_end + - date_2000_start + - date_2099_end + - date_2100_start + - start_of_time + - end_of_time +---*/ + +var date_1899_end = -2208988800001; +var date_1900_start = -2208988800000; +var date_1969_end = -1; +var date_1970_start = 0; +var date_1999_end = 946684799999; +var date_2000_start = 946684800000; +var date_2099_end = 4102444799999; +var date_2100_start = 4102444800000; + +var start_of_time = -8.64e15; +var end_of_time = 8.64e15; + +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +---*/ + +function isConstructor(f) { + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/this-bad-object.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/this-bad-object.js new file mode 100644 index 0000000000..3cf6cbfb69 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/this-bad-object.js @@ -0,0 +1,29 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Igalia, S.L. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +description: > + Throws a TypeError if this is not a DateTimeFormat object +features: [Intl.DateTimeFormat-formatRange] +---*/ + +const formatRangeToParts = Intl.DateTimeFormat.prototype.formatRangeToParts; + +assert.throws(TypeError, function() { + formatRangeToParts.call({}); +}, "{}"); + +assert.throws(TypeError, function() { + formatRangeToParts.call(new Date()); +}, "new Date()"); + +assert.throws(TypeError, function() { + formatRangeToParts.call(Intl.DateTimeFormat); +}, "Intl.DateTimeFormat"); + +assert.throws(TypeError, function() { + formatRangeToParts.call(Intl.DateTimeFormat.prototype); +}, "Intl.DateTimeFormat.prototype"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/this-is-not-object-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/this-is-not-object-throws.js new file mode 100644 index 0000000000..cf04cdc0af --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatRangeToParts/this-is-not-object-throws.js @@ -0,0 +1,50 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-formatRange is not released yet +// Copyright 2019 Google, Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + Throws a TypeError if this is not Object. +info: | + Intl.DateTimeFormat.prototype.formatRangeToParts ( startDate , endDate ) + + 1. Let dtf be this value. + 2. If Type(dtf) is not Object, throw a TypeError exception. + +features: [Intl.DateTimeFormat-formatRange, Symbol] +---*/ + +let formatRangeToParts = Intl.DateTimeFormat.prototype.formatRangeToParts; +let d1 = new Date("1997-08-22T00:00"); +let d2 = new Date("1999-06-26T00:00"); + +assert.throws(TypeError, function() { + formatRangeToParts.call(undefined, d1, d2); +}, "undefined"); + +assert.throws(TypeError, function() { + formatRangeToParts.call(null, d1, d2); +}, "null"); + +assert.throws(TypeError, function() { + formatRangeToParts.call(42, d1, d2); +}, "number"); + +assert.throws(TypeError, function() { + formatRangeToParts.call("foo", d1, d2); +}, "string"); + +assert.throws(TypeError, function() { + formatRangeToParts.call(false, d1, d2); +}, "false"); + +assert.throws(TypeError, function() { + formatRangeToParts.call(true, d1, d2); +}, "true"); + +var s = Symbol('3'); +assert.throws(TypeError, function() { + formatRangeToParts.call(s, d1, d2); +}, "symbol"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/browser.js diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-constructor-not-called.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-constructor-not-called.js new file mode 100644 index 0000000000..9c63ee3e52 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-constructor-not-called.js @@ -0,0 +1,38 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimepattern +description: | + The Date constructor is not called to convert the input value. +info: > + 12.4.4 Intl.DateTimeFormat.prototype.formatToParts ( date ) + + ... + 4. If date is undefined, then + ... + 5. Else, + a. Let x be ? ToNumber(date). + 5. Return ? FormatDateTimeToParts(dtf, x). + + 12.1.6 PartitionDateTimePattern ( dateTimeFormat, x ) + + 1. Let x be TimeClip(x). + 2. If x is NaN, throw a RangeError exception. + 3. ... +---*/ + +var dtf = new Intl.DateTimeFormat(); + +var dateTimeString = "2017-11-10T14:09:00.000Z"; + +// |dateTimeString| is valid ISO-8601 style date/time string. +assert.notSameValue(new Date(dateTimeString), NaN); + +// Ensure string input values are not converted to time values by calling the +// Date constructor. +assert.throws(RangeError, function() { + dtf.formatToParts(dateTimeString); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-is-infinity-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-is-infinity-throws.js new file mode 100644 index 0000000000..071c07ed45 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-is-infinity-throws.js @@ -0,0 +1,35 @@ +// Copyright 2016 Leonardo Balter. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +description: > + Throws a RangeError if date arg is cast to an Infinity value +info: | + Intl.DateTimeFormat.prototype.formatToParts ([ date ]) + + 4. If _date_ is not provided or is *undefined*, then + a. Let _x_ be *%Date_now%*(). + 5. Else, + a. Let _x_ be ? ToNumber(_date_). + 6. Return ? FormatDateTimeToParts(_dtf_, _x_). + + FormatDateTimeToParts(dateTimeFormat, x) + + 1. Let _parts_ be ? PartitionDateTimePattern(_dateTimeFormat_, _x_). + + PartitionDateTimePattern (dateTimeFormat, x) + + 1. If _x_ is not a finite Number, throw a *RangeError* exception. +---*/ + +var dtf = new Intl.DateTimeFormat(["pt-BR"]); + +assert.throws(RangeError, function() { + dtf.formatToParts(Infinity); +}, "+Infinity"); + +assert.throws(RangeError, function() { + dtf.formatToParts(-Infinity); +}, "-Infinity"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-is-nan-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-is-nan-throws.js new file mode 100644 index 0000000000..ab062734e0 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-is-nan-throws.js @@ -0,0 +1,35 @@ +// Copyright 2016 Leonardo Balter. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +description: > + Throws a RangeError if date arg is cast to NaN +info: | + Intl.DateTimeFormat.prototype.formatToParts ([ date ]) + + 4. If _date_ is not provided or is *undefined*, then + a. Let _x_ be *%Date_now%*(). + 5. Else, + a. Let _x_ be ? ToNumber(_date_). + 6. Return ? FormatDateTimeToParts(_dtf_, _x_). + + FormatDateTimeToParts(dateTimeFormat, x) + + 1. Let _parts_ be ? PartitionDateTimePattern(_dateTimeFormat_, _x_). + + PartitionDateTimePattern (dateTimeFormat, x) + + 1. If _x_ is not a finite Number, throw a *RangeError* exception. +---*/ + +var dtf = new Intl.DateTimeFormat(["pt-BR"]); + +assert.throws(RangeError, function() { + dtf.formatToParts(NaN); +}); + +assert.throws(RangeError, function() { + dtf.formatToParts("lol"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-long-en.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-long-en.js new file mode 100644 index 0000000000..c3595070d0 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-long-en.js @@ -0,0 +1,109 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet +// Copyright 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks basic handling of dayPeriod, long format. +features: [Intl.DateTimeFormat-dayPeriod] +---*/ + +const d0000 = new Date(2017, 11, 12, 0, 0, 0, 0); +const d0100 = new Date(2017, 11, 12, 1, 0, 0, 0); +const d0200 = new Date(2017, 11, 12, 2, 0, 0, 0); +const d0300 = new Date(2017, 11, 12, 3, 0, 0, 0); +const d0400 = new Date(2017, 11, 12, 4, 0, 0, 0); +const d0500 = new Date(2017, 11, 12, 5, 0, 0, 0); +const d0600 = new Date(2017, 11, 12, 6, 0, 0, 0); +const d0700 = new Date(2017, 11, 12, 7, 0, 0, 0); +const d0800 = new Date(2017, 11, 12, 8, 0, 0, 0); +const d0900 = new Date(2017, 11, 12, 9, 0, 0, 0); +const d1000 = new Date(2017, 11, 12, 10, 0, 0, 0); +const d1100 = new Date(2017, 11, 12, 11, 0, 0, 0); +const d1200 = new Date(2017, 11, 12, 12, 0, 0, 0); +const d1300 = new Date(2017, 11, 12, 13, 0, 0, 0); +const d1400 = new Date(2017, 11, 12, 14, 0, 0, 0); +const d1500 = new Date(2017, 11, 12, 15, 0, 0, 0); +const d1600 = new Date(2017, 11, 12, 16, 0, 0, 0); +const d1700 = new Date(2017, 11, 12, 17, 0, 0, 0); +const d1800 = new Date(2017, 11, 12, 18, 0, 0, 0); +const d1900 = new Date(2017, 11, 12, 19, 0, 0, 0); +const d2000 = new Date(2017, 11, 12, 20, 0, 0, 0); +const d2100 = new Date(2017, 11, 12, 21, 0, 0, 0); +const d2200 = new Date(2017, 11, 12, 22, 0, 0, 0); +const d2300 = new Date(2017, 11, 12, 23, 0, 0, 0); + +const long = new Intl.DateTimeFormat('en', { dayPeriod: 'long' }); + +function assertParts(parts, expected, message) { + assert.sameValue(parts.length, 1, `length should be 1, ${message}`); + assert.sameValue(parts[0].value, expected, `expected part value. ${message}`); + assert.sameValue(parts[0].type, 'dayPeriod', `part type is dayPeriod. ${message}`); +} + +assertParts(long.formatToParts(d0000), 'at night', '00:00, long format'); +assertParts(long.formatToParts(d0100), 'at night', '01:00, long format'); +assertParts(long.formatToParts(d0200), 'at night', '02:00, long format'); +assertParts(long.formatToParts(d0300), 'at night', '03:00, long format'); +assertParts(long.formatToParts(d0400), 'at night', '04:00, long format'); +assertParts(long.formatToParts(d0500), 'at night', '05:00, long format'); +assertParts(long.formatToParts(d0600), 'in the morning', '06:00, long format'); +assertParts(long.formatToParts(d0700), 'in the morning', '07:00, long format'); +assertParts(long.formatToParts(d0800), 'in the morning', '08:00, long format'); +assertParts(long.formatToParts(d0900), 'in the morning', '09:00, long format'); +assertParts(long.formatToParts(d1000), 'in the morning', '10:00, long format'); +assertParts(long.formatToParts(d1100), 'in the morning', '11:00, long format'); +assertParts(long.formatToParts(d1200), 'noon', '12:00, long format'); +assertParts(long.formatToParts(d1300), 'in the afternoon', '13:00, long format'); +assertParts(long.formatToParts(d1400), 'in the afternoon', '14:00, long format'); +assertParts(long.formatToParts(d1500), 'in the afternoon', '15:00, long format'); +assertParts(long.formatToParts(d1600), 'in the afternoon', '16:00, long format'); +assertParts(long.formatToParts(d1700), 'in the afternoon', '17:00, long format'); +assertParts(long.formatToParts(d1800), 'in the evening', '18:00, long format'); +assertParts(long.formatToParts(d1900), 'in the evening', '19:00, long format'); +assertParts(long.formatToParts(d2000), 'in the evening', '20:00, long format'); +assertParts(long.formatToParts(d2100), 'at night', '21:00, long format'); +assertParts(long.formatToParts(d2200), 'at night', '22:00, long format'); +assertParts(long.formatToParts(d2300), 'at night', '23:00, long format'); + +const longNumeric = new Intl.DateTimeFormat('en', { + dayPeriod: 'long', + hour: 'numeric' +}); + +function assertPartsNumeric(parts, hour, expected, message) { + assert.sameValue(parts.length, 3, `length should be 3, ${message}`); + assert.sameValue(parts[0].value, hour, `hour part value. ${message}`); + assert.sameValue(parts[0].type, 'hour', `hour part type. ${message}`); + assert.sameValue(parts[1].value, ' ', `literal part value. ${message}`); + assert.sameValue(parts[1].type, 'literal', `literal part type. ${message}`); + assert.sameValue(parts[2].value, expected, `expected part value. ${message}`); + assert.sameValue(parts[2].type, 'dayPeriod', `expected part type. ${message}`); +} + +assertPartsNumeric(longNumeric.formatToParts(d0000), '12', 'at night', '00:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d0100), '1', 'at night', '01:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d0200), '2', 'at night', '02:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d0300), '3', 'at night', '03:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d0400), '4', 'at night', '04:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d0500), '5', 'at night', '05:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d0600), '6', 'in the morning', '06:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d0700), '7', 'in the morning', '07:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d0800), '8', 'in the morning', '08:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d0900), '9', 'in the morning', '09:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d1000), '10', 'in the morning', '10:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d1100), '11', 'in the morning', '11:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d1200), '12', 'noon', '12:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d1300), '1', 'in the afternoon', '13:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d1400), '2', 'in the afternoon', '14:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d1500), '3', 'in the afternoon', '15:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d1600), '4', 'in the afternoon', '16:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d1700), '5', 'in the afternoon', '17:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d1800), '6', 'in the evening', '18:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d1900), '7', 'in the evening', '19:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d2000), '8', 'in the evening', '20:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d2100), '9', 'at night', '21:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d2200), '10', 'at night', '22:00, long-numeric'); +assertPartsNumeric(longNumeric.formatToParts(d2300), '11', 'at night', '23:00, long-numeric'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-narrow-en.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-narrow-en.js new file mode 100644 index 0000000000..72a24eacbc --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-narrow-en.js @@ -0,0 +1,109 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet +// Copyright 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks basic handling of dayPeriod, narrow format. +features: [Intl.DateTimeFormat-dayPeriod] +---*/ + +const d0000 = new Date(2017, 11, 12, 0, 0, 0, 0); +const d0100 = new Date(2017, 11, 12, 1, 0, 0, 0); +const d0200 = new Date(2017, 11, 12, 2, 0, 0, 0); +const d0300 = new Date(2017, 11, 12, 3, 0, 0, 0); +const d0400 = new Date(2017, 11, 12, 4, 0, 0, 0); +const d0500 = new Date(2017, 11, 12, 5, 0, 0, 0); +const d0600 = new Date(2017, 11, 12, 6, 0, 0, 0); +const d0700 = new Date(2017, 11, 12, 7, 0, 0, 0); +const d0800 = new Date(2017, 11, 12, 8, 0, 0, 0); +const d0900 = new Date(2017, 11, 12, 9, 0, 0, 0); +const d1000 = new Date(2017, 11, 12, 10, 0, 0, 0); +const d1100 = new Date(2017, 11, 12, 11, 0, 0, 0); +const d1200 = new Date(2017, 11, 12, 12, 0, 0, 0); +const d1300 = new Date(2017, 11, 12, 13, 0, 0, 0); +const d1400 = new Date(2017, 11, 12, 14, 0, 0, 0); +const d1500 = new Date(2017, 11, 12, 15, 0, 0, 0); +const d1600 = new Date(2017, 11, 12, 16, 0, 0, 0); +const d1700 = new Date(2017, 11, 12, 17, 0, 0, 0); +const d1800 = new Date(2017, 11, 12, 18, 0, 0, 0); +const d1900 = new Date(2017, 11, 12, 19, 0, 0, 0); +const d2000 = new Date(2017, 11, 12, 20, 0, 0, 0); +const d2100 = new Date(2017, 11, 12, 21, 0, 0, 0); +const d2200 = new Date(2017, 11, 12, 22, 0, 0, 0); +const d2300 = new Date(2017, 11, 12, 23, 0, 0, 0); + +const narrow = new Intl.DateTimeFormat('en', { dayPeriod: 'narrow' }); + +function assertParts(parts, expected, message) { + assert.sameValue(parts.length, 1, `length should be 1, ${message}`); + assert.sameValue(parts[0].value, expected, `expected part value. ${message}`); + assert.sameValue(parts[0].type, 'dayPeriod', `part type is dayPeriod. ${message}`); +} + +assertParts(narrow.formatToParts(d0000), 'at night', '00:00, narrow format'); +assertParts(narrow.formatToParts(d0100), 'at night', '01:00, narrow format'); +assertParts(narrow.formatToParts(d0200), 'at night', '02:00, narrow format'); +assertParts(narrow.formatToParts(d0300), 'at night', '03:00, narrow format'); +assertParts(narrow.formatToParts(d0400), 'at night', '04:00, narrow format'); +assertParts(narrow.formatToParts(d0500), 'at night', '05:00, narrow format'); +assertParts(narrow.formatToParts(d0600), 'in the morning', '06:00, narrow format'); +assertParts(narrow.formatToParts(d0700), 'in the morning', '07:00, narrow format'); +assertParts(narrow.formatToParts(d0800), 'in the morning', '08:00, narrow format'); +assertParts(narrow.formatToParts(d0900), 'in the morning', '09:00, narrow format'); +assertParts(narrow.formatToParts(d1000), 'in the morning', '10:00, narrow format'); +assertParts(narrow.formatToParts(d1100), 'in the morning', '11:00, narrow format'); +assertParts(narrow.formatToParts(d1200), 'n', '12:00, narrow format'); +assertParts(narrow.formatToParts(d1300), 'in the afternoon', '13:00, narrow format'); +assertParts(narrow.formatToParts(d1400), 'in the afternoon', '14:00, narrow format'); +assertParts(narrow.formatToParts(d1500), 'in the afternoon', '15:00, narrow format'); +assertParts(narrow.formatToParts(d1600), 'in the afternoon', '16:00, narrow format'); +assertParts(narrow.formatToParts(d1700), 'in the afternoon', '17:00, narrow format'); +assertParts(narrow.formatToParts(d1800), 'in the evening', '18:00, narrow format'); +assertParts(narrow.formatToParts(d1900), 'in the evening', '19:00, narrow format'); +assertParts(narrow.formatToParts(d2000), 'in the evening', '20:00, narrow format'); +assertParts(narrow.formatToParts(d2100), 'at night', '21:00, narrow format'); +assertParts(narrow.formatToParts(d2200), 'at night', '22:00, narrow format'); +assertParts(narrow.formatToParts(d2300), 'at night', '23:00, narrow format'); + +const narrowNumeric = new Intl.DateTimeFormat('en', { + dayPeriod: 'narrow', + hour: 'numeric' +}); + +function assertPartsNumeric(parts, hour, expected, message) { + assert.sameValue(parts.length, 3, `length should be 3, ${message}`); + assert.sameValue(parts[0].value, hour, `hour part value. ${message}`); + assert.sameValue(parts[0].type, 'hour', `hour part type. ${message}`); + assert.sameValue(parts[1].value, ' ', `literal part value. ${message}`); + assert.sameValue(parts[1].type, 'literal', `literal part type. ${message}`); + assert.sameValue(parts[2].value, expected, `expected part value. ${message}`); + assert.sameValue(parts[2].type, 'dayPeriod', `expected part type. ${message}`); +} + +assertPartsNumeric(narrowNumeric.formatToParts(d0000), '12', 'at night', '00:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d0100), '1', 'at night', '01:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d0200), '2', 'at night', '02:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d0300), '3', 'at night', '03:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d0400), '4', 'at night', '04:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d0500), '5', 'at night', '05:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d0600), '6', 'in the morning', '06:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d0700), '7', 'in the morning', '07:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d0800), '8', 'in the morning', '08:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d0900), '9', 'in the morning', '09:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d1000), '10', 'in the morning', '10:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d1100), '11', 'in the morning', '11:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d1200), '12', 'n', '12:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d1300), '1', 'in the afternoon', '13:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d1400), '2', 'in the afternoon', '14:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d1500), '3', 'in the afternoon', '15:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d1600), '4', 'in the afternoon', '16:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d1700), '5', 'in the afternoon', '17:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d1800), '6', 'in the evening', '18:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d1900), '7', 'in the evening', '19:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d2000), '8', 'in the evening', '20:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d2100), '9', 'at night', '21:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d2200), '10', 'at night', '22:00, narrow-numeric'); +assertPartsNumeric(narrowNumeric.formatToParts(d2300), '11', 'at night', '23:00, narrow-numeric'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-short-en.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-short-en.js new file mode 100644 index 0000000000..8301bfca84 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/dayPeriod-short-en.js @@ -0,0 +1,109 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet +// Copyright 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks basic handling of dayPeriod, short format. +features: [Intl.DateTimeFormat-dayPeriod] +---*/ + +const d0000 = new Date(2017, 11, 12, 0, 0, 0, 0); +const d0100 = new Date(2017, 11, 12, 1, 0, 0, 0); +const d0200 = new Date(2017, 11, 12, 2, 0, 0, 0); +const d0300 = new Date(2017, 11, 12, 3, 0, 0, 0); +const d0400 = new Date(2017, 11, 12, 4, 0, 0, 0); +const d0500 = new Date(2017, 11, 12, 5, 0, 0, 0); +const d0600 = new Date(2017, 11, 12, 6, 0, 0, 0); +const d0700 = new Date(2017, 11, 12, 7, 0, 0, 0); +const d0800 = new Date(2017, 11, 12, 8, 0, 0, 0); +const d0900 = new Date(2017, 11, 12, 9, 0, 0, 0); +const d1000 = new Date(2017, 11, 12, 10, 0, 0, 0); +const d1100 = new Date(2017, 11, 12, 11, 0, 0, 0); +const d1200 = new Date(2017, 11, 12, 12, 0, 0, 0); +const d1300 = new Date(2017, 11, 12, 13, 0, 0, 0); +const d1400 = new Date(2017, 11, 12, 14, 0, 0, 0); +const d1500 = new Date(2017, 11, 12, 15, 0, 0, 0); +const d1600 = new Date(2017, 11, 12, 16, 0, 0, 0); +const d1700 = new Date(2017, 11, 12, 17, 0, 0, 0); +const d1800 = new Date(2017, 11, 12, 18, 0, 0, 0); +const d1900 = new Date(2017, 11, 12, 19, 0, 0, 0); +const d2000 = new Date(2017, 11, 12, 20, 0, 0, 0); +const d2100 = new Date(2017, 11, 12, 21, 0, 0, 0); +const d2200 = new Date(2017, 11, 12, 22, 0, 0, 0); +const d2300 = new Date(2017, 11, 12, 23, 0, 0, 0); + +const short = new Intl.DateTimeFormat('en', { dayPeriod: 'short' }); + +function assertParts(parts, expected, message) { + assert.sameValue(parts.length, 1, `length should be 1, ${message}`); + assert.sameValue(parts[0].value, expected, `expected part value. ${message}`); + assert.sameValue(parts[0].type, 'dayPeriod', `part type is dayPeriod. ${message}`); +} + +assertParts(short.formatToParts(d0000), 'at night', '00:00, short format'); +assertParts(short.formatToParts(d0100), 'at night', '01:00, short format'); +assertParts(short.formatToParts(d0200), 'at night', '02:00, short format'); +assertParts(short.formatToParts(d0300), 'at night', '03:00, short format'); +assertParts(short.formatToParts(d0400), 'at night', '04:00, short format'); +assertParts(short.formatToParts(d0500), 'at night', '05:00, short format'); +assertParts(short.formatToParts(d0600), 'in the morning', '06:00, short format'); +assertParts(short.formatToParts(d0700), 'in the morning', '07:00, short format'); +assertParts(short.formatToParts(d0800), 'in the morning', '08:00, short format'); +assertParts(short.formatToParts(d0900), 'in the morning', '09:00, short format'); +assertParts(short.formatToParts(d1000), 'in the morning', '10:00, short format'); +assertParts(short.formatToParts(d1100), 'in the morning', '11:00, short format'); +assertParts(short.formatToParts(d1200), 'noon', '12:00, short format'); +assertParts(short.formatToParts(d1300), 'in the afternoon', '13:00, short format'); +assertParts(short.formatToParts(d1400), 'in the afternoon', '14:00, short format'); +assertParts(short.formatToParts(d1500), 'in the afternoon', '15:00, short format'); +assertParts(short.formatToParts(d1600), 'in the afternoon', '16:00, short format'); +assertParts(short.formatToParts(d1700), 'in the afternoon', '17:00, short format'); +assertParts(short.formatToParts(d1800), 'in the evening', '18:00, short format'); +assertParts(short.formatToParts(d1900), 'in the evening', '19:00, short format'); +assertParts(short.formatToParts(d2000), 'in the evening', '20:00, short format'); +assertParts(short.formatToParts(d2100), 'at night', '21:00, short format'); +assertParts(short.formatToParts(d2200), 'at night', '22:00, short format'); +assertParts(short.formatToParts(d2300), 'at night', '23:00, short format'); + +const shortNumeric = new Intl.DateTimeFormat('en', { + dayPeriod: 'short', + hour: 'numeric' +}); + +function assertPartsNumeric(parts, hour, expected, message) { + assert.sameValue(parts.length, 3, `length should be 3, ${message}`); + assert.sameValue(parts[0].value, hour, `hour part value. ${message}`); + assert.sameValue(parts[0].type, 'hour', `hour part type. ${message}`); + assert.sameValue(parts[1].value, ' ', `literal part value. ${message}`); + assert.sameValue(parts[1].type, 'literal', `literal part type. ${message}`); + assert.sameValue(parts[2].value, expected, `expected part value. ${message}`); + assert.sameValue(parts[2].type, 'dayPeriod', `expected part type. ${message}`); +} + +assertPartsNumeric(shortNumeric.formatToParts(d0000), '12', 'at night', '00:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d0100), '1', 'at night', '01:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d0200), '2', 'at night', '02:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d0300), '3', 'at night', '03:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d0400), '4', 'at night', '04:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d0500), '5', 'at night', '05:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d0600), '6', 'in the morning', '06:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d0700), '7', 'in the morning', '07:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d0800), '8', 'in the morning', '08:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d0900), '9', 'in the morning', '09:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d1000), '10', 'in the morning', '10:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d1100), '11', 'in the morning', '11:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d1200), '12', 'noon', '12:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d1300), '1', 'in the afternoon', '13:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d1400), '2', 'in the afternoon', '14:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d1500), '3', 'in the afternoon', '15:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d1600), '4', 'in the afternoon', '16:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d1700), '5', 'in the afternoon', '17:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d1800), '6', 'in the evening', '18:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d1900), '7', 'in the evening', '19:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d2000), '8', 'in the evening', '20:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d2100), '9', 'at night', '21:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d2200), '10', 'at night', '22:00, short-numeric'); +assertPartsNumeric(shortNumeric.formatToParts(d2300), '11', 'at night', '23:00, short-numeric'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/formatToParts.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/formatToParts.js new file mode 100644 index 0000000000..d1898c5c1d --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/formatToParts.js @@ -0,0 +1,19 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +description: Property type and descriptor. +includes: [propertyHelper.js] +---*/ + +assert.sameValue( + typeof Intl.DateTimeFormat.prototype.formatToParts, + 'function', + '`typeof Intl.DateTimeFormat.prototype.formatToParts` is `function`' +); + +verifyNotEnumerable(Intl.DateTimeFormat.prototype, 'formatToParts'); +verifyWritable(Intl.DateTimeFormat.prototype, 'formatToParts'); +verifyConfigurable(Intl.DateTimeFormat.prototype, 'formatToParts'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/fractionalSecondDigits.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/fractionalSecondDigits.js new file mode 100644 index 0000000000..30d96b4d31 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/fractionalSecondDigits.js @@ -0,0 +1,69 @@ +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: Checks basic handling of fractionalSecondDigits. +features: [Intl.DateTimeFormat-fractionalSecondDigits] +locale: [en-US] +---*/ + +const d1 = new Date(2019, 7, 10, 1, 2, 3, 234); +const d2 = new Date(2019, 7, 10, 1, 2, 3, 567); + +function assertParts(parts, minute, second, fractionalSecond, message) { + if (fractionalSecond === null) { + assert.sameValue(parts.length, 3, `length should be 3, ${message}`); + } else { + assert.sameValue(parts.length, 5, `length should be 5, ${message}`); + } + assert.sameValue(parts[0].value, minute, `minute part value. ${message}`); + assert.sameValue(parts[0].type, 'minute', `minute part type. ${message}`); + assert.sameValue(parts[1].value, ':', `literal part value. ${message}`); + assert.sameValue(parts[1].type, 'literal', `literal part type. ${message}`); + assert.sameValue(parts[2].value, second, `second part value. ${message}`); + assert.sameValue(parts[2].type, 'second', `second part type. ${message}`); + if (fractionalSecond !== null) { + assert.sameValue(parts[3].value, '.', `literal part value. ${message}`); + assert.sameValue(parts[3].type, 'literal', `literal part type. ${message}`); + assert.sameValue(parts[4].value, fractionalSecond, `fractionalSecond part value. ${message}`); + assert.sameValue(parts[4].type, 'fractionalSecond', `fractionalSecond part type. ${message}`); + } +} + +assert.throws(RangeError, () => { + new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 0}); +}, "fractionalSecondDigits 0 should throw RangeError for out of range"); + +assert.throws(RangeError, () => { + new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 4}); +}, "fractionalSecondDigits 4 should throw RangeError for out of range"); + +let dtf = new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric"}); +assertParts(dtf.formatToParts(d1), "02", "03", null, "no fractionalSecondDigits round down"); +assertParts(dtf.formatToParts(d2), "02", "03", null, "no fractionalSecondDigits round down"); + +dtf = new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: undefined}); +assertParts(dtf.formatToParts(d1), "02", "03", null, "no fractionalSecondDigits round down"); +assertParts(dtf.formatToParts(d2), "02", "03", null, "no fractionalSecondDigits round down"); + +dtf = new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 1}); +assertParts(dtf.formatToParts(d1), "02", "03", "2", "1 fractionalSecondDigits round down"); +assertParts(dtf.formatToParts(d2), "02", "03", "5", "1 fractionalSecondDigits round down"); + +dtf = new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 2}); +assertParts(dtf.formatToParts(d1), "02", "03", "23", "2 fractionalSecondDigits round down"); +assertParts(dtf.formatToParts(d2), "02", "03", "56", "2 fractionalSecondDigits round down"); + +dtf = new Intl.DateTimeFormat( + 'en', { minute: "numeric", second: "numeric", fractionalSecondDigits: 3}); +assertParts(dtf.formatToParts(d1), "02", "03", "234", "3 fractionalSecondDigits round down"); +assertParts(dtf.formatToParts(d2), "02", "03", "567", "3 fractionalSecondDigits round down"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/length.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/length.js new file mode 100644 index 0000000000..cc596ada97 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/length.js @@ -0,0 +1,15 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +description: Intl.DateTimeFormat.prototype.formatToParts.length. +includes: [propertyHelper.js] +---*/ +verifyProperty(Intl.DateTimeFormat.prototype.formatToParts, 'length', { + value: 1, + enumerable: false, + writable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/main.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/main.js new file mode 100644 index 0000000000..79ad4f324e --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/main.js @@ -0,0 +1,75 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +description: Tests for existance and behavior of Intl.DateTimeFormat.prototype.formatToParts +---*/ + +function reduce(parts) { + return parts.map(part => part.value).join(''); +} + +function compareFTPtoFormat(locales, options, value) { + const dtf = new Intl.DateTimeFormat(locales, options); + assert.sameValue( + dtf.format(value), + reduce(dtf.formatToParts(value)), + `Expected the same value for value ${value}, + locales: ${locales} and options: ${options}` + ); +} + +compareFTPtoFormat(); +compareFTPtoFormat('pl'); +compareFTPtoFormat(['pl']); +compareFTPtoFormat([]); +compareFTPtoFormat(['de'], undefined, 0); +compareFTPtoFormat(['de'], undefined, -10); +compareFTPtoFormat(['de'], undefined, 25324234235); +compareFTPtoFormat(['de'], { + day: '2-digit' +}, Date.now()); +compareFTPtoFormat(['de'], { + day: 'numeric', + year: '2-digit' +}, Date.now()); +compareFTPtoFormat(['ar'], { + month: 'numeric', + day: 'numeric', + year: '2-digit' +}, Date.now()); + +const actualPartTypes = new Intl.DateTimeFormat('en-us', { + weekday: 'long', + era: 'long', + year: 'numeric', + month: 'numeric', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + second: 'numeric', + hour12: true, + timeZone: 'UTC', + timeZoneName: 'long' +}).formatToParts(Date.UTC(2012, 11, 17, 3, 0, 42)) + .map(part => part.type); + +const legalPartTypes = [ + 'weekday', + 'era', + 'year', + 'month', + 'day', + 'hour', + 'minute', + 'second', + 'literal', + 'dayPeriod', + 'timeZoneName', +]; + +actualPartTypes.forEach(function(type) { + assert(legalPartTypes.includes(type), `${type} is not a legal type`); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/name.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/name.js new file mode 100644 index 0000000000..92b4805ee9 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/name.js @@ -0,0 +1,15 @@ +// Copyright 2016 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +description: Intl.DateTimeFormat.prototype.formatToParts.name value and descriptor. +includes: [propertyHelper.js] +---*/ +verifyProperty(Intl.DateTimeFormat.prototype.formatToParts, 'name', { + value: 'formatToParts', + enumerable: false, + writable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/pattern-on-calendar.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/pattern-on-calendar.js new file mode 100644 index 0000000000..9a87da8dbc --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/pattern-on-calendar.js @@ -0,0 +1,55 @@ +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Checks the DateTimeFormat choose different patterns based + on calendar. +locale: [en] +---*/ + +let calendars = [ + "buddhist", + "chinese", + "coptic", + "dangi", + "ethiopic", + "ethioaa", + "gregory", + "hebrew", + "indian", + "islamic", + "islamic-civil", + "islamic-rgsa", + "islamic-tbla", + "islamic-umalqura", + "japanese", + "persian", + "roc" +]; +let date = new Date(); + +// serialize parts to a string by considering only the type and literal. +function serializeTypesAndLiteral(parts) { + let types = parts.map(part => { + if (part.type == "literal") { + return `${part.type}(${part.value})`; + } + return part.type; + }); + return types.join(":"); +} + +let df = new Intl.DateTimeFormat("en"); +let base = serializeTypesAndLiteral(df.formatToParts(date)); + +const foundDifferentPattern = calendars.some(function(calendar) { + let cdf = new Intl.DateTimeFormat("en-u-ca-" + calendar); + return base != serializeTypesAndLiteral(cdf.formatToParts(date)); +}); + +// Expect at least some calendar use different pattern. +assert.sameValue(foundDifferentPattern, true); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/related-year-zh.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/related-year-zh.js new file mode 100644 index 0000000000..1033404e00 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/related-year-zh.js @@ -0,0 +1,35 @@ +// Copyright 2019 Google Inc, Igalia S.L. All rights reserved. +// Copyright 2020 Apple Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimepattern +description: > + Checks the output of 'relatedYear' and 'yearName' type, and + the choice of pattern based on calendar. +locale: [zh-u-ca-chinese] +---*/ + +const df = new Intl.DateTimeFormat("zh-u-ca-chinese", {year: "numeric"}); +const date = new Date(2019, 5, 1); +const actual = df.formatToParts(date); + +const expected = [ + {type: "relatedYear", value: "2019"}, + {type: "yearName", value: "己亥"}, + {type: "literal", value: "年"}, +]; + +assert.sameValue(Array.isArray(actual), true, 'actual is Array'); + +if (actual.length <= 2) { + expected.shift(); // removes the relatedYear +} + +actual.forEach(({ type, value }, i) => { + const { type: eType, value: eValue } = expected[i]; + assert.sameValue(type, eType, `actual[${i}].type should be ${eType}`); + assert.sameValue(value, eValue, `actual[${i}].value should be ${eValue}`); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/related-year.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/related-year.js new file mode 100644 index 0000000000..92aae9e730 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/related-year.js @@ -0,0 +1,23 @@ +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimepattern +description: > + Checks the output of 'relatedYear' and 'yearName' type, and + the choose of pattern base on calendar. +locale: [en-u-ca-chinese] +---*/ + +let df = new Intl.DateTimeFormat("en-u-ca-chinese", {year: "numeric"}); +let parts = df.formatToParts(new Date()); +var relatedYearCount = 0; +var yearNameCount = 0; +parts.forEach(function(part) { + relatedYearCount += (part.type == "relatedYear") ? 1 : 0; + yearNameCount += (part.type == "yearName") ? 1 : 0; +}); +assert.sameValue(relatedYearCount > 0, true); +assert.sameValue(yearNameCount > 0, true); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/return-abrupt-tonumber-date.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/return-abrupt-tonumber-date.js new file mode 100644 index 0000000000..b8141a3776 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/return-abrupt-tonumber-date.js @@ -0,0 +1,44 @@ +// Copyright 2016 Leonardo Balter. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +description: > + Return abrupt completions from ToNumber(date) +info: | + Intl.DateTimeFormat.prototype.formatToParts ([ date ]) + + 4. If _date_ is not provided or is *undefined*, then + a. Let _x_ be *%Date_now%*(). + 5. Else, + a. Let _x_ be ? ToNumber(_date_). +features: [Symbol] +---*/ + +var obj1 = { + valueOf: function() { + throw new Test262Error(); + } +}; + +var obj2 = { + toString: function() { + throw new Test262Error(); + } +}; + +var dtf = new Intl.DateTimeFormat(["pt-BR"]); + +assert.throws(Test262Error, function() { + dtf.formatToParts(obj1); +}, "valueOf"); + +assert.throws(Test262Error, function() { + dtf.formatToParts(obj2); +}, "toString"); + +var s = Symbol('1'); +assert.throws(TypeError, function() { + dtf.formatToParts(s); +}, "symbol"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/shell.js new file mode 100644 index 0000000000..62c6315a70 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/shell.js @@ -0,0 +1,31 @@ +// GENERATED, DO NOT EDIT +// file: dateConstants.js +// Copyright (C) 2009 the Sputnik authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + Collection of date-centric values +defines: + - date_1899_end + - date_1900_start + - date_1969_end + - date_1970_start + - date_1999_end + - date_2000_start + - date_2099_end + - date_2100_start + - start_of_time + - end_of_time +---*/ + +var date_1899_end = -2208988800001; +var date_1900_start = -2208988800000; +var date_1969_end = -1; +var date_1970_start = 0; +var date_1999_end = 946684799999; +var date_2000_start = 946684800000; +var date_2099_end = 4102444799999; +var date_2100_start = 4102444800000; + +var start_of_time = -8.64e15; +var end_of_time = 8.64e15; diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/this-has-not-internal-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/this-has-not-internal-throws.js new file mode 100644 index 0000000000..18dae83a16 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/this-has-not-internal-throws.js @@ -0,0 +1,19 @@ +// Copyright 2016 Leonardo Balter. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +description: > + Throws a TypeError if this is not a DateTimeFormat object +---*/ + +var formatToParts = Intl.DateTimeFormat.prototype.formatToParts; + +assert.throws(TypeError, function() { + formatToParts.call({}); +}, "{}"); + +assert.throws(TypeError, function() { + formatToParts.call(new Date()); +}, "new Date()"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/this-is-not-object-throws.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/this-is-not-object-throws.js new file mode 100644 index 0000000000..0837bfb1ca --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/this-is-not-object-throws.js @@ -0,0 +1,40 @@ +// Copyright 2016 Leonardo Balter. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +description: Throws a TypeError if this is not Object +features: [Symbol] +---*/ + +var formatToParts = Intl.DateTimeFormat.prototype.formatToParts; + +assert.throws(TypeError, function() { + formatToParts.call(undefined); +}, "undefined"); + +assert.throws(TypeError, function() { + formatToParts.call(null); +}, "null"); + +assert.throws(TypeError, function() { + formatToParts.call(42); +}, "number"); + +assert.throws(TypeError, function() { + formatToParts.call("foo"); +}, "string"); + +assert.throws(TypeError, function() { + formatToParts.call(false); +}, "false"); + +assert.throws(TypeError, function() { + formatToParts.call(true); +}, "true"); + +var s = Symbol('1'); +assert.throws(TypeError, function() { + formatToParts.call(s); +}, "symbol"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/time-clip-near-time-boundaries.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/time-clip-near-time-boundaries.js new file mode 100644 index 0000000000..61599ebbc1 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/time-clip-near-time-boundaries.js @@ -0,0 +1,39 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimepattern +description: | + TimeClip is applied when calling Intl.DateTimeFormat.prototype.formatToParts. +info: > + 12.1.6 PartitionDateTimePattern ( dateTimeFormat, x ) + + 1. Let x be TimeClip(x). + 2. If x is NaN, throw a RangeError exception. + 3. ... + + 20.3.1.15 TimeClip ( time ) + ... + 2. If abs(time) > 8.64 × 10^15, return NaN. + ... + +includes: [dateConstants.js] +---*/ + +var dtf = new Intl.DateTimeFormat(); + +// Test values near the start of the ECMAScript time range. +assert.throws(RangeError, function() { + dtf.formatToParts(start_of_time - 1); +}); +assert.sameValue(typeof dtf.formatToParts(start_of_time), "object"); +assert.sameValue(typeof dtf.formatToParts(start_of_time + 1), "object"); + +// Test values near the end of the ECMAScript time range. +assert.sameValue(typeof dtf.formatToParts(end_of_time - 1), "object"); +assert.sameValue(typeof dtf.formatToParts(end_of_time), "object"); +assert.throws(RangeError, function() { + dtf.formatToParts(end_of_time + 1); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/time-clip-to-integer.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/time-clip-to-integer.js new file mode 100644 index 0000000000..576b08ca92 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/time-clip-to-integer.js @@ -0,0 +1,43 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-partitiondatetimepattern +description: | + TimeClip applies ToInteger on its input value. +info: > + 12.1.6 PartitionDateTimePattern ( dateTimeFormat, x ) + + 1. Let x be TimeClip(x). + 2. ... + + 20.3.1.15 TimeClip ( time ) + ... + 3. Let clippedTime be ! ToInteger(time). + 4. If clippedTime is -0, set clippedTime to +0. + 5. Return clippedTime. +---*/ + +// Switch to a time format instead of using DateTimeFormat's default date-only format. +var dtf = new Intl.DateTimeFormat(undefined, { + hour: "numeric", minute: "numeric", second: "numeric" +}); + +function formatAsString(dtf, time) { + return dtf.formatToParts(time).map(part => part.value).join(""); +} + +var expected = formatAsString(dtf, 0); + +assert.sameValue(formatAsString(dtf, -0.9), expected, "formatToParts(-0.9)"); +assert.sameValue(formatAsString(dtf, -0.5), expected, "formatToParts(-0.5)"); +assert.sameValue(formatAsString(dtf, -0.1), expected, "formatToParts(-0.1)"); +assert.sameValue(formatAsString(dtf, -Number.MIN_VALUE), expected, "formatToParts(-Number.MIN_VALUE)"); +assert.sameValue(formatAsString(dtf, -0), expected, "formatToParts(-0)"); +assert.sameValue(formatAsString(dtf, +0), expected, "formatToParts(+0)"); +assert.sameValue(formatAsString(dtf, Number.MIN_VALUE), expected, "formatToParts(Number.MIN_VALUE)"); +assert.sameValue(formatAsString(dtf, 0.1), expected, "formatToParts(0.1)"); +assert.sameValue(formatAsString(dtf, 0.5), expected, "formatToParts(0.5)"); +assert.sameValue(formatAsString(dtf, 0.9), expected, "formatToParts(0.9)"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/prop-desc.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/prop-desc.js new file mode 100644 index 0000000000..711e47059a --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/prop-desc.js @@ -0,0 +1,19 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +es5id: 12.2.1 +description: > + Tests that Intl.DateTimeFormat.prototype has the required + attributes. +author: Norbert Lindenberg +includes: [propertyHelper.js] +---*/ + +verifyProperty(Intl.DateTimeFormat, "prototype", { + writable: false, + enumerable: false, + configurable: false, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/basic.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/basic.js new file mode 100644 index 0000000000..294b8f4d80 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/basic.js @@ -0,0 +1,75 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +es5id: 12.3.3 +description: > + Tests that the object returned by + Intl.DateTimeFormat.prototype.resolvedOptions has the right + properties. +author: Norbert Lindenberg +includes: [testIntl.js, propertyHelper.js] +---*/ + +var actual = new Intl.DateTimeFormat().resolvedOptions(); + +var actual2 = new Intl.DateTimeFormat().resolvedOptions(); +assert.notSameValue(actual2, actual, "resolvedOptions returned the same object twice."); + +// source: CLDR file common/bcp47/calendar.xml; version CLDR 32. +var calendars = [ + "buddhist", + "chinese", + "coptic", + "dangi", + "ethioaa", + "ethiopic-amete-alem", + "ethiopic", + "gregory", + "hebrew", + "indian", + "islamic", + "islamic-umalqura", + "islamic-tbla", + "islamic-civil", + "islamic-rgsa", + "iso8601", + "japanese", + "persian", + "roc", + "islamicc", +]; + +// this assumes the default values where the specification provides them +assert(isCanonicalizedStructurallyValidLanguageTag(actual.locale), + "Invalid locale: " + actual.locale); +assert.notSameValue(calendars.indexOf(actual.calendar), -1, + "Invalid calendar: " + actual.calendar); +assert(isValidNumberingSystem(actual.numberingSystem), + "Invalid numbering system: " + actual.numberingSystem); +assert(isCanonicalizedStructurallyValidTimeZoneName(actual.timeZone), + "Invalid time zone: " + actual.timeZone); +assert.notSameValue(["2-digit", "numeric"].indexOf(actual.year), -1, + "Invalid year: " + actual.year); +assert.notSameValue(["2-digit", "numeric", "narrow", "short", "long"].indexOf(actual.month), -1, + "Invalid month: " + actual.month); +assert.notSameValue(["2-digit", "numeric"].indexOf(actual.day), -1, + "Invalid day: " + actual.day); + +var dataPropertyDesc = { writable: true, enumerable: true, configurable: true }; +verifyProperty(actual, "locale", dataPropertyDesc); +verifyProperty(actual, "calendar", dataPropertyDesc); +verifyProperty(actual, "numberingSystem", dataPropertyDesc); +verifyProperty(actual, "timeZone", dataPropertyDesc); +verifyProperty(actual, "weekday", undefined); +verifyProperty(actual, "era", undefined); +verifyProperty(actual, "year", dataPropertyDesc); +verifyProperty(actual, "month", dataPropertyDesc); +verifyProperty(actual, "day", dataPropertyDesc); +verifyProperty(actual, "hour", undefined); +verifyProperty(actual, "minute", undefined); +verifyProperty(actual, "second", undefined); +verifyProperty(actual, "timeZoneName", undefined); +verifyProperty(actual, "hour12", undefined); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/browser.js diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/builtin.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/builtin.js new file mode 100644 index 0000000000..643376e7e2 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/builtin.js @@ -0,0 +1,30 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +es5id: 12.3.3_L15 +description: > + Tests that Intl.DateTimeFormat.prototype.resolvedOptions meets + the requirements for built-in objects defined by the introduction + of chapter 17 of the ECMAScript Language Specification. +author: Norbert Lindenberg +includes: [isConstructor.js] +features: [Reflect.construct] +---*/ + +assert.sameValue(Object.prototype.toString.call(Intl.DateTimeFormat.prototype.resolvedOptions), "[object Function]", + "The [[Class]] internal property of a built-in function must be " + + "\"Function\"."); + +assert(Object.isExtensible(Intl.DateTimeFormat.prototype.resolvedOptions), + "Built-in objects must be extensible."); + +assert.sameValue(Object.getPrototypeOf(Intl.DateTimeFormat.prototype.resolvedOptions), Function.prototype); + +assert.sameValue(Intl.DateTimeFormat.prototype.resolvedOptions.hasOwnProperty("prototype"), false, + "Built-in functions that aren't constructors must not have a prototype property."); + +assert.sameValue(isConstructor(Intl.DateTimeFormat.prototype.resolvedOptions), false, + "Built-in functions don't implement [[Construct]] unless explicitly specified."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-dateStyle.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-dateStyle.js new file mode 100644 index 0000000000..e6e06a1ad0 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-dateStyle.js @@ -0,0 +1,69 @@ +// Copyright 2019 Mozilla Corporation, Igalia S.L. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-Intl.DateTimeFormat.prototype.resolvedOptions +description: > + Intl.DateTimeFormat.prototype.resolvedOptions properly + reflect hourCycle settings when using dateStyle. +features: [Intl.DateTimeFormat-datetimestyle] +---*/ + +const hcValues = ["h11", "h12", "h23", "h24"]; +const hour12Values = ["h11", "h12"]; + +for (const dateStyle of ["full", "long", "medium", "short"]) { + assert.sameValue(new Intl.DateTimeFormat([], { dateStyle }).resolvedOptions().dateStyle, + dateStyle, + `Should support dateStyle=${dateStyle}`); + + /* Values passed via unicode extension key work */ + + for (const hcValue of hcValues) { + const resolvedOptions = new Intl.DateTimeFormat(`de-u-hc-${hcValue}`, { + dateStyle, + }).resolvedOptions(); + + assert.sameValue(resolvedOptions.hourCycle, undefined); + assert.sameValue(resolvedOptions.hour12, undefined); + } + + /* Values passed via options work */ + + for (const hcValue of hcValues) { + const resolvedOptions = new Intl.DateTimeFormat("en-US", { + dateStyle, + hourCycle: hcValue + }).resolvedOptions(); + + assert.sameValue(resolvedOptions.hourCycle, undefined); + assert.sameValue(resolvedOptions.hour12, undefined); + } + + let resolvedOptions = new Intl.DateTimeFormat("en-US-u-hc-h12", { + dateStyle, + hourCycle: "h23" + }).resolvedOptions(); + + assert.sameValue(resolvedOptions.hourCycle, undefined); + assert.sameValue(resolvedOptions.hour12, undefined); + + resolvedOptions = new Intl.DateTimeFormat("fr", { + dateStyle, + hour12: true, + hourCycle: "h23" + }).resolvedOptions(); + + assert.sameValue(resolvedOptions.hourCycle, undefined); + assert.sameValue(resolvedOptions.hour12, undefined); + + resolvedOptions = new Intl.DateTimeFormat("fr-u-hc-h24", { + dateStyle, + hour12: true, + }).resolvedOptions(); + + assert.sameValue(resolvedOptions.hourCycle, undefined); + assert.sameValue(resolvedOptions.hour12, undefined); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-default.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-default.js new file mode 100644 index 0000000000..906518c44b --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-default.js @@ -0,0 +1,58 @@ +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-Intl.DateTimeFormat.prototype.resolvedOptions +description: > + Intl.DateTimeFormat.prototype.resolvedOptions properly + reflect hourCycle settings. +info: | + 12.4.5 Intl.DateTimeFormat.prototype.resolvedOptions() + + 12.1.1 InitializeDateTimeFormat ( dateTimeFormat, locales, options ) + 29. If dateTimeFormat.[[Hour]] is not undefined, then + a. Let hcDefault be dataLocaleData.[[hourCycle]]. + b. Let hc be dateTimeFormat.[[HourCycle]]. + c. If hc is null, then + i. Set hc to hcDefault. + d. If hour12 is not undefined, then + i. If hour12 is true, then + 1. If hcDefault is "h11" or "h23", then + a. Set hc to "h11". + 2. Else, + a. Set hc to "h12". + ii. Else, + 1. Assert: hour12 is false. + 2. If hcDefault is "h11" or "h23", then + a. Set hc to "h23". + 3. Else, + a. Set hc to "h24". + e. Set dateTimeFormat.[[HourCycle]] to hc. + +locale: [en, fr, it, ja, zh, ko, ar, hi] +---*/ + +let locales = ["en", "fr", "it", "ja", "zh", "ko", "ar", "hi"]; + +locales.forEach(function(locale) { + let hcDefault = (new Intl.DateTimeFormat(locale, {hour: "numeric"})) + .resolvedOptions().hourCycle; + if (hcDefault == "h11" || hcDefault == "h23") { + assert.sameValue("h11", + (new Intl.DateTimeFormat(locale, {hour: "numeric", hour12: true})) + .resolvedOptions().hourCycle); + assert.sameValue("h23", + (new Intl.DateTimeFormat(locale, {hour: "numeric", hour12: false})) + .resolvedOptions().hourCycle); + } else { + assert.sameValue(true, hcDefault == "h12" || hcDefault == "h24") + assert.sameValue("h12", + (new Intl.DateTimeFormat(locale, {hour: "numeric", hour12: true})) + .resolvedOptions().hourCycle); + assert.sameValue("h24", + (new Intl.DateTimeFormat(locale, {hour: "numeric", hour12: false})) + .resolvedOptions().hourCycle); + } +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-timeStyle.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-timeStyle.js new file mode 100644 index 0000000000..7fc96e2adb --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle-timeStyle.js @@ -0,0 +1,89 @@ +// Copyright 2019 Mozilla Corporation, Igalia S.L. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-Intl.DateTimeFormat.prototype.resolvedOptions +description: > + Intl.DateTimeFormat.prototype.resolvedOptions properly + reflect hourCycle settings when using timeStyle. +includes: [propertyHelper.js] +features: [Intl.DateTimeFormat-datetimestyle] +---*/ + +const hcValues = ["h11", "h12", "h23", "h24"]; +const hour12Values = ["h11", "h12"]; +const dataPropertyDesc = { writable: true, enumerable: true, configurable: true }; + +for (const timeStyle of ["full", "long", "medium", "short"]) { + assert.sameValue(new Intl.DateTimeFormat([], { timeStyle }).resolvedOptions().timeStyle, + timeStyle, + `Should support timeStyle=${timeStyle}`); + + /* Values passed via unicode extension key work */ + + for (const hcValue of hcValues) { + const resolvedOptions = new Intl.DateTimeFormat(`de-u-hc-${hcValue}`, { + timeStyle, + }).resolvedOptions(); + + assert.sameValue(resolvedOptions.hourCycle, hcValue); + assert.sameValue(resolvedOptions.hour12, hour12Values.includes(hcValue)); + } + + /* Values passed via options work */ + + for (const hcValue of hcValues) { + const resolvedOptions = new Intl.DateTimeFormat("en-US", { + timeStyle, + hourCycle: hcValue + }).resolvedOptions(); + + assert.sameValue(resolvedOptions.hourCycle, hcValue); + assert.sameValue(resolvedOptions.hour12, hour12Values.includes(hcValue)); + + verifyProperty(resolvedOptions, "hourCycle", dataPropertyDesc); + verifyProperty(resolvedOptions, "hour12", dataPropertyDesc); + } + + /* When both extension key and option is passed, option takes precedence */ + + let resolvedOptions = new Intl.DateTimeFormat("en-US-u-hc-h12", { + timeStyle, + hourCycle: "h23" + }).resolvedOptions(); + + assert.sameValue(resolvedOptions.hourCycle, "h23"); + assert.sameValue(resolvedOptions.hour12, false); + + verifyProperty(resolvedOptions, "hourCycle", dataPropertyDesc); + verifyProperty(resolvedOptions, "hour12", dataPropertyDesc); + + /* When hour12 and hourCycle are set, hour12 takes precedence */ + + resolvedOptions = new Intl.DateTimeFormat("fr", { + timeStyle, + hour12: true, + hourCycle: "h23" + }).resolvedOptions(); + + assert(hour12Values.includes(resolvedOptions.hourCycle)); + assert.sameValue(resolvedOptions.hour12, true); + + verifyProperty(resolvedOptions, "hourCycle", dataPropertyDesc); + verifyProperty(resolvedOptions, "hour12", dataPropertyDesc); + + /* When hour12 and extension key are set, hour12 takes precedence */ + + resolvedOptions = new Intl.DateTimeFormat("fr-u-hc-h24", { + timeStyle, + hour12: true, + }).resolvedOptions(); + + assert(hour12Values.includes(resolvedOptions.hourCycle)); + assert.sameValue(resolvedOptions.hour12, true); + + verifyProperty(resolvedOptions, "hourCycle", dataPropertyDesc); + verifyProperty(resolvedOptions, "hour12", dataPropertyDesc); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle.js new file mode 100644 index 0000000000..07c3913191 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/hourCycle.js @@ -0,0 +1,101 @@ +// Copyright 2017 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-Intl.DateTimeFormat.prototype.resolvedOptions +description: > + Intl.DateTimeFormat.prototype.resolvedOptions properly + reflect hourCycle settings. +info: | + 12.4.5 Intl.DateTimeFormat.prototype.resolvedOptions() + +includes: [propertyHelper.js] +---*/ + +/* Values passed via unicode extension key work */ + +const hcValues = ['h11', 'h12', 'h23', 'h24']; +const hour12Values = ['h11', 'h12']; + +const dataPropertyDesc = { writable: true, enumerable: true, configurable: true }; + +for (const hcValue of hcValues) { + const resolvedOptions = new Intl.DateTimeFormat(`de-u-hc-${hcValue}`, { + hour: 'numeric' + }).resolvedOptions(); + + assert.sameValue(resolvedOptions.hourCycle, hcValue); + assert.sameValue(resolvedOptions.hour12, hour12Values.includes(hcValue)); + + verifyProperty(resolvedOptions, 'hourCycle', dataPropertyDesc); + verifyProperty(resolvedOptions, 'hour12', dataPropertyDesc); +} + +/* Values passed via options work */ + +for (const hcValue of hcValues) { + const resolvedOptions = new Intl.DateTimeFormat(`en-US`, { + hour: 'numeric', + hourCycle: hcValue + }).resolvedOptions(); + + assert.sameValue(resolvedOptions.hourCycle, hcValue); + assert.sameValue(resolvedOptions.hour12, hour12Values.includes(hcValue)); + + verifyProperty(resolvedOptions, 'hourCycle', dataPropertyDesc); + verifyProperty(resolvedOptions, 'hour12', dataPropertyDesc); +} + +/* When both extension key and option is passed, option takes precedence */ + +let resolvedOptions = new Intl.DateTimeFormat(`en-US-u-hc-h12`, { + hour: 'numeric', + hourCycle: 'h23' +}).resolvedOptions(); + +assert.sameValue(resolvedOptions.hourCycle, 'h23'); +assert.sameValue(resolvedOptions.hour12, false); + +verifyProperty(resolvedOptions, 'hourCycle', dataPropertyDesc); +verifyProperty(resolvedOptions, 'hour12', dataPropertyDesc); + +/* When hour12 and hourCycle are set, hour12 takes precedence */ + +resolvedOptions = new Intl.DateTimeFormat(`fr`, { + hour: 'numeric', + hour12: true, + hourCycle: 'h23' +}).resolvedOptions(); + +assert(hour12Values.includes(resolvedOptions.hourCycle)); +assert.sameValue(resolvedOptions.hour12, true); + +verifyProperty(resolvedOptions, 'hourCycle', dataPropertyDesc); +verifyProperty(resolvedOptions, 'hour12', dataPropertyDesc); + +/* When hour12 and extension key are set, hour12 takes precedence */ + +resolvedOptions = new Intl.DateTimeFormat(`fr-u-hc-h24`, { + hour: 'numeric', + hour12: true, +}).resolvedOptions(); + +assert(hour12Values.includes(resolvedOptions.hourCycle)); +assert.sameValue(resolvedOptions.hour12, true); + +verifyProperty(resolvedOptions, 'hourCycle', dataPropertyDesc); +verifyProperty(resolvedOptions, 'hour12', dataPropertyDesc); + +/* When the hour is not in the pattern, hourCycle and hour12 are not defined. */ + +resolvedOptions = new Intl.DateTimeFormat("fr", { + hourCycle: "h12", + hour12: false, +}).resolvedOptions(); + +assert.sameValue(resolvedOptions.hour, undefined, + "Precondition: hour should not be included by default"); +assert.sameValue(resolvedOptions.hourCycle, undefined); +assert.sameValue(resolvedOptions.hour12, undefined); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/length.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/length.js new file mode 100644 index 0000000000..5e2070baf0 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/length.js @@ -0,0 +1,33 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype.resolvedoptions +description: > + Intl.DateTimeFormat.prototype.resolvedOptions.length is 0. +info: | + Intl.DateTimeFormat.prototype.resolvedOptions () + + 17 ECMAScript Standard Built-in Objects: + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + Unless otherwise specified, the length property of a built-in function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. + +includes: [propertyHelper.js] +---*/ + +assert.sameValue(Intl.DateTimeFormat.prototype.resolvedOptions.length, 0); + +verifyNotEnumerable(Intl.DateTimeFormat.prototype.resolvedOptions, "length"); +verifyNotWritable(Intl.DateTimeFormat.prototype.resolvedOptions, "length"); +verifyConfigurable(Intl.DateTimeFormat.prototype.resolvedOptions, "length"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/name.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/name.js new file mode 100644 index 0000000000..808c268e74 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/name.js @@ -0,0 +1,28 @@ +// Copyright (C) 2016 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DateTimeFormat.prototype.resolvedOptions +description: > + Intl.DateTimeFormat.prototype.resolvedOptions.name is "resolvedOptions". +info: | + 12.4.4 Intl.DateTimeFormat.prototype.resolvedOptions () + + 17 ECMAScript Standard Built-in Objects: + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +---*/ + +assert.sameValue(Intl.DateTimeFormat.prototype.resolvedOptions.name, "resolvedOptions"); + +verifyNotEnumerable(Intl.DateTimeFormat.prototype.resolvedOptions, "name"); +verifyNotWritable(Intl.DateTimeFormat.prototype.resolvedOptions, "name"); +verifyConfigurable(Intl.DateTimeFormat.prototype.resolvedOptions, "name"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-dayPeriod.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-dayPeriod.js new file mode 100644 index 0000000000..fa49b52b68 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-dayPeriod.js @@ -0,0 +1,40 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype.resolvedoptions +description: Verifies the property order for the object returned by resolvedOptions(). +includes: [arrayContains.js] +features: [Intl.DateTimeFormat-dayPeriod] +---*/ + +const options = new Intl.DateTimeFormat([], { + "dayPeriod": "short", + "hour": "numeric", + "minute": "numeric", +}).resolvedOptions(); + +const expected = [ + "locale", + "calendar", + "numberingSystem", + "timeZone", + "hourCycle", + "hour12", + "dayPeriod", + "hour", + "minute", +]; + +let actual = Object.getOwnPropertyNames(options); + +// Ensure all expected items are in actual and also allow other properties +// implemented in new proposals. +assert(arrayContains(actual, expected)); +for (var i = 1; i < expected.length; i++) { + // Ensure the order as expected but allow additional new property in between + assert(actual.indexOf(expected[i-1]) < actual.indexOf(expected[i])); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-fractionalSecondDigits.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-fractionalSecondDigits.js new file mode 100644 index 0000000000..a5160bb3c8 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-fractionalSecondDigits.js @@ -0,0 +1,37 @@ +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype.resolvedoptions +description: Verifies the property order for the object returned by resolvedOptions(). +includes: [arrayContains.js] +features: [Intl.DateTimeFormat-fractionalSecondDigits] +---*/ + +const options = new Intl.DateTimeFormat([], { + "fractionalSecondDigits": 3, + "minute": "numeric", + "second": "numeric", +}).resolvedOptions(); + +const expected = [ + "locale", + "calendar", + "numberingSystem", + "timeZone", + "minute", + "second", + "fractionalSecondDigits", +]; + +let actual = Object.getOwnPropertyNames(options); + +// Ensure all expected items are in actual and also allow other properties +// implemented in new proposals. +assert(arrayContains(actual, expected)); +for (var i = 1; i < expected.length; i++) { + // Ensure the order as expected but allow additional new property in between + assert(actual.indexOf(expected[i-1]) < actual.indexOf(expected[i])); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-style.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-style.js new file mode 100644 index 0000000000..338701c4de --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order-style.js @@ -0,0 +1,43 @@ +// Copyright 2018 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype.resolvedoptions +description: Verifies the property order for the object returned by resolvedOptions(). +includes: [arrayContains.js] +features: [Intl.DateTimeFormat-datetimestyle] +---*/ + +const options = new Intl.DateTimeFormat([], { + "hourCycle": "h24", + "weekday": "short", + "era": "short", + "year": "numeric", + "month": "numeric", + "day": "numeric", + "hour": "numeric", + "minute": "numeric", + "second": "numeric", + "timeZoneName": "short", +}).resolvedOptions(); + +const expected = [ + "locale", + "calendar", + "numberingSystem", + "timeZone", + "hourCycle", + "hour12", +]; + +let actual = Object.getOwnPropertyNames(options); + +// Ensure all expected items are in actual and also allow other properties +// implemented in new proposals. +assert(arrayContains(actual, expected)); +for (var i = 1; i < expected.length; i++) { + // Ensure the order as expected but allow additional new property in between + assert(actual.indexOf(expected[i-1]) < actual.indexOf(expected[i])); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order.js new file mode 100644 index 0000000000..8f50b76b2d --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/order.js @@ -0,0 +1,51 @@ +// Copyright 2018 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype.resolvedoptions +description: Verifies the property order for the object returned by resolvedOptions(). +includes: [arrayContains.js] +---*/ + +const options = new Intl.DateTimeFormat([], { + "hourCycle": "h24", + "weekday": "short", + "era": "short", + "year": "numeric", + "month": "numeric", + "day": "numeric", + "hour": "numeric", + "minute": "numeric", + "second": "numeric", + "timeZoneName": "short", +}).resolvedOptions(); + +const expected = [ + "locale", + "calendar", + "numberingSystem", + "timeZone", + "hourCycle", + "hour12", + "weekday", + "era", + "year", + "month", + "day", + "hour", + "minute", + "second", + "timeZoneName", +]; + +let actual = Object.getOwnPropertyNames(options); + +// Ensure all expected items are in actual and also allow other properties +// implemented in new proposals. +assert(arrayContains(actual, expected)); +for (var i = 1; i < expected.length; i++) { + // Ensure the order as expected but allow additional new property in between + assert(actual.indexOf(expected[i-1]) < actual.indexOf(expected[i])); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/prop-desc.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/prop-desc.js new file mode 100644 index 0000000000..c4f9742f07 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/prop-desc.js @@ -0,0 +1,31 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype.resolvedoptions +description: > + "resolvedOptions" property of Intl.DateTimeFormat.prototype. +info: | + Intl.DateTimeFormat.prototype.resolvedOptions () + + 7 Requirements for Standard Built-in ECMAScript Objects + + Unless specified otherwise in this document, the objects, functions, and constructors + described in this standard are subject to the generic requirements and restrictions + specified for standard built-in ECMAScript objects in the ECMAScript 2018 Language + Specification, 9th edition, clause 17, or successor. + + 17 ECMAScript Standard Built-in Objects: + + Every other data property described in clauses 18 through 26 and in Annex B.2 has the + attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } + unless otherwise specified. + +includes: [propertyHelper.js] +---*/ + +verifyNotEnumerable(Intl.DateTimeFormat.prototype, "resolvedOptions"); +verifyWritable(Intl.DateTimeFormat.prototype, "resolvedOptions"); +verifyConfigurable(Intl.DateTimeFormat.prototype, "resolvedOptions"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/resolved-locale-with-hc-unicode.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/resolved-locale-with-hc-unicode.js new file mode 100644 index 0000000000..5b0516ca27 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/resolved-locale-with-hc-unicode.js @@ -0,0 +1,89 @@ +// Copyright 2018 André Bargull. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +esid: sec-Intl.DateTimeFormat.prototype.resolvedOptions +description: > + The resolved locale doesn't include a hc Unicode extension value if the + hour12 or hourCycle option is also present. +info: | + 12.1.1 InitializeDateTimeFormat(dateTimeFormat, locales, options) + ... + 6. Let hour12 be ? GetOption(options, "hour12", "boolean", undefined, undefined). + 7. Let hourCycle be ? GetOption(options, "hourCycle", "string", « "h11", "h12", "h23", "h24" », undefined). + 8. If hour12 is not undefined, then + a. Let hourCycle be null. + 9. Set opt.[[hc]] to hourCycle. + ... + + 9.2.6 ResolveLocale(availableLocales, requestedLocales, options, relevantExtensionKeys, localeData) + ... + 8. For each element key of relevantExtensionKeys in List order, do + ... + i. If options has a field [[<key>]], then + i. Let optionsValue be options.[[<key>]]. + ii. Assert: Type(optionsValue) is either String, Undefined, or Null. + iii. If keyLocaleData contains optionsValue, then + 1. If SameValue(optionsValue, value) is false, then + a. Let value be optionsValue. + b. Let supportedExtensionAddition be "". + ... +---*/ + +var defaultLocale = new Intl.DateTimeFormat().resolvedOptions().locale; +var defaultLocaleWithHourCycle = defaultLocale + "-u-hc-h11"; + +function assertLocale(locale, expectedLocale, options, message) { + var resolved = new Intl.DateTimeFormat(locale, { + hour: "2-digit", + hour12: options.hour12, + hourCycle: options.hourCycle, + }).resolvedOptions(); + assert.sameValue(resolved.locale, expectedLocale, message + " (With hour option.)"); + + // Also test the case when no hour option is present at all. + // The resolved options don't include hour12 and hourCycle if the date-time + // formatter doesn't include an hour option. This restriction doesn't apply + // to the hc Unicode extension value. + resolved = new Intl.DateTimeFormat(locale, { + hour12: options.hour12, + hourCycle: options.hourCycle, + }).resolvedOptions(); + assert.sameValue(resolved.locale, expectedLocale, message + " (Without hour option.)"); +} + +assertLocale(defaultLocaleWithHourCycle, defaultLocale, { + hour12: false, + hourCycle: "h23", +}, "hour12 and hourCycle options and hc Unicode extension value are present."); + +assertLocale(defaultLocaleWithHourCycle, defaultLocale, { + hour12: false, +}, "hour12 option and hc Unicode extension value are present."); + +assertLocale(defaultLocaleWithHourCycle, defaultLocale, { + hourCycle: "h23", +}, "hourCycle option and hc Unicode extension value are present."); + +assertLocale(defaultLocaleWithHourCycle, defaultLocaleWithHourCycle, { +}, "Only hc Unicode extension value is present."); + +// And make sure the hc Unicode extension doesn't get added if it's not present +// in the requested locale. +assertLocale(defaultLocale, defaultLocale, { + hour12: false, + hourCycle: "h23", +}, "hour12 and hourCycle options are present, but no hc Unicode extension value."); + +assertLocale(defaultLocale, defaultLocale, { + hour12: false, +}, "hourCycle option is present, but no hc Unicode extension value."); + +assertLocale(defaultLocale, defaultLocale, { + hourCycle: "h23", +}, "hourCycle option is present, but no hc Unicode extension value."); + +assertLocale(defaultLocale, defaultLocale, { +}, "No options are present and no hc Unicode extension value."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/shell.js new file mode 100644 index 0000000000..857452379f --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/shell.js @@ -0,0 +1,50 @@ +// GENERATED, DO NOT EDIT +// file: arrayContains.js +// Copyright (C) 2017 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + Verify that a subArray is contained within an array. +defines: [arrayContains] +---*/ + +/** + * @param {Array} array + * @param {Array} subArray + */ + +function arrayContains(array, subArray) { + var found; + for (var i = 0; i < subArray.length; i++) { + found = false; + for (var j = 0; j < array.length; j++) { + if (subArray[i] === array[j]) { + found = true; + break; + } + } + if (!found) { + return false; + } + } + return true; +} + +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +---*/ + +function isConstructor(f) { + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/shell.js diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/this-value-datetimeformat-prototype.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/this-value-datetimeformat-prototype.js new file mode 100644 index 0000000000..34db44141b --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/this-value-datetimeformat-prototype.js @@ -0,0 +1,17 @@ +// Copyright 2012 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-properties-of-intl-datetimeformat-prototype-object +description: > + Tests that Intl.DateTimeFormat.prototype is not an object that has + been initialized as an Intl.DateTimeFormat. +author: Roozbeh Pournader +---*/ + +// test by calling a function that should fail as "this" is not an object +// initialized as an Intl.DateTimeFormat +assert.throws(TypeError, () => Intl.DateTimeFormat.prototype.format(0), + "Intl.DateTimeFormat's prototype is not an object that has been initialized as an Intl.DateTimeFormat"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/this-value-not-datetimeformat.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/this-value-not-datetimeformat.js new file mode 100644 index 0000000000..4805ca2f69 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/this-value-not-datetimeformat.js @@ -0,0 +1,28 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 12.3_b +description: > + Tests that Intl.DateTimeFormat.prototype functions throw a + TypeError if called on a non-object value or an object that hasn't + been initialized as a DateTimeFormat. +author: Norbert Lindenberg +---*/ + +var functions = { + "format getter": Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, "format").get, + resolvedOptions: Intl.DateTimeFormat.prototype.resolvedOptions +}; +var invalidTargets = [undefined, null, true, 0, "DateTimeFormat", [], {}]; + +Object.getOwnPropertyNames(functions).forEach(function (functionName) { + var f = functions[functionName]; + invalidTargets.forEach(function (target) { + assert.throws(TypeError, function() { + f.call(target); + }, "Calling " + functionName + " on " + target + " was not rejected."); + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/browser.js diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/shell.js diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString-changed-tag.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString-changed-tag.js new file mode 100644 index 0000000000..69b853ad0a --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString-changed-tag.js @@ -0,0 +1,30 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype-@@tostringtag +description: > + Object.prototype.toString utilizes Intl.DateTimeFormat.prototype[@@toStringTag]. +info: | + Object.prototype.toString ( ) + + [...] + 14. Else, let builtinTag be "Object". + 15. Let tag be ? Get(O, @@toStringTag). + 16. If Type(tag) is not String, set tag to builtinTag. + 17. Return the string-concatenation of "[object ", tag, and "]". + + Intl.DateTimeFormat.prototype [ @@toStringTag ] + + This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +features: [Symbol.toStringTag] +---*/ + +Object.defineProperty(Intl.DateTimeFormat.prototype, Symbol.toStringTag, { + value: "test262", +}); + +assert.sameValue(Object.prototype.toString.call(Intl.DateTimeFormat.prototype), "[object test262]"); +assert.sameValue(Object.prototype.toString.call(new Intl.DateTimeFormat()), "[object test262]"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString-removed-tag.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString-removed-tag.js new file mode 100644 index 0000000000..170562a720 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString-removed-tag.js @@ -0,0 +1,24 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype-@@tostringtag +description: > + Object.prototype.toString doesn't special-case neither Intl.DateTimeFormat instances nor its prototype. +info: | + Object.prototype.toString ( ) + + [...] + 14. Else, let builtinTag be "Object". + 15. Let tag be ? Get(O, @@toStringTag). + 16. If Type(tag) is not String, set tag to builtinTag. + 17. Return the string-concatenation of "[object ", tag, and "]". +features: [Symbol.toStringTag] +---*/ + +delete Intl.DateTimeFormat.prototype[Symbol.toStringTag]; + +assert.sameValue(Object.prototype.toString.call(Intl.DateTimeFormat.prototype), "[object Object]"); +assert.sameValue(Object.prototype.toString.call(new Intl.DateTimeFormat()), "[object Object]"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString.js new file mode 100644 index 0000000000..f8e5d3db50 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toString.js @@ -0,0 +1,26 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype-@@tostringtag +description: > + Object.prototype.toString utilizes Intl.DateTimeFormat.prototype[@@toStringTag]. +info: | + Object.prototype.toString ( ) + + [...] + 14. Else, let builtinTag be "Object". + 15. Let tag be ? Get(O, @@toStringTag). + 16. If Type(tag) is not String, set tag to builtinTag. + 17. Return the string-concatenation of "[object ", tag, and "]". + + Intl.DateTimeFormat.prototype [ @@toStringTag ] + + The initial value of the @@toStringTag property is the String value "Intl.DateTimeFormat". +features: [Symbol.toStringTag] +---*/ + +assert.sameValue(Object.prototype.toString.call(Intl.DateTimeFormat.prototype), "[object Intl.DateTimeFormat]"); +assert.sameValue(Object.prototype.toString.call(new Intl.DateTimeFormat()), "[object Intl.DateTimeFormat]"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toStringTag.js b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toStringTag.js new file mode 100644 index 0000000000..b118adeac8 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/toStringTag/toStringTag.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.prototype-@@tostringtag +description: > + Property descriptor of Intl.DateTimeFormat.prototype[@@toStringTag]. +info: | + Intl.DateTimeFormat.prototype [ @@toStringTag ] + + The initial value of the @@toStringTag property is the String value "Intl.DateTimeFormat". + + This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. +features: [Symbol.toStringTag] +includes: [propertyHelper.js] +---*/ + +verifyProperty(Intl.DateTimeFormat.prototype, Symbol.toStringTag, { + value: "Intl.DateTimeFormat", + writable: false, + enumerable: false, + configurable: true, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/required-date-time-formats.js b/js/src/tests/test262/intl402/DateTimeFormat/required-date-time-formats.js new file mode 100644 index 0000000000..6a17fc5edb --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/required-date-time-formats.js @@ -0,0 +1,48 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +es5id: 12.2.3_c +description: > + Tests that Intl.DateTimeFormat provides the required date-time + format component subsets. +author: Norbert Lindenberg +includes: [testIntl.js] +---*/ + +var locales = ["de-DE", "en-US", "hi-IN", "id-ID", "ja-JP", "th-TH", "zh-Hans-CN", "zh-Hant-TW", "zxx"]; +var subsets = [ + {weekday: "long", year: "numeric", month: "numeric", day: "numeric", + hour: "numeric", minute: "numeric", second: "numeric"}, + {weekday: "long", year: "numeric", month: "numeric", day: "numeric"}, + {year: "numeric", month: "numeric", day: "numeric"}, + {year: "numeric", month: "numeric"}, + {month: "numeric", day: "numeric"}, + {hour: "numeric", minute: "numeric", second: "numeric"}, + {hour: "numeric", minute: "numeric"} +]; + +locales.forEach(function (locale) { + subsets.forEach(function (subset) { + var format = new Intl.DateTimeFormat([locale], subset); + var actual = format.resolvedOptions(); + getDateTimeComponents().forEach(function (component) { + if (actual.hasOwnProperty(component)) { + assert(subset.hasOwnProperty(component), + "Unrequested component " + component + + " added to requested subset " + JSON.stringify(subset) + + "; locale " + locale + "."); + assert.notSameValue(getDateTimeComponentValues(component).indexOf(actual[component]), -1, + "Invalid value " + actual[component] + " for date-time component " + component + "." + + " (Testing locale " + locale + "; subset " + JSON.stringify(subset) + ")"); + } else { + assert.sameValue(subset.hasOwnProperty(component), false, + "Missing component " + component + + " from requested subset " + JSON.stringify(subset) + + "; locale " + locale + "."); + } + }); + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/shell.js diff --git a/js/src/tests/test262/intl402/DateTimeFormat/subclassing.js b/js/src/tests/test262/intl402/DateTimeFormat/subclassing.js new file mode 100644 index 0000000000..c7167676b8 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/subclassing.js @@ -0,0 +1,30 @@ +// Copyright 2011-2012 Norbert Lindenberg. All rights reserved. +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 12.1.2 +description: Tests that Intl.DateTimeFormat can be subclassed. +author: Norbert Lindenberg +includes: [compareArray.js] +---*/ + +// get a date-time format and have it format an array of dates for comparison with the subclass +var locales = ["tlh", "id", "en"]; +var a = [new Date(0), Date.now(), new Date(Date.parse("1989-11-09T17:57:00Z"))]; +var referenceDateTimeFormat = new Intl.DateTimeFormat(locales); +var referenceFormatted = a.map(referenceDateTimeFormat.format); + +class MyDateTimeFormat extends Intl.DateTimeFormat { + constructor(locales, options) { + super(locales, options); + // could initialize MyDateTimeFormat properties + } + // could add methods to MyDateTimeFormat.prototype +} + +var format = new MyDateTimeFormat(locales); +var actual = a.map(format.format); +assert.compareArray(actual, referenceFormatted); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/basic.js b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/basic.js new file mode 100644 index 0000000000..8b4e2884e7 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/basic.js @@ -0,0 +1,25 @@ +// Copyright 2012 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 12.2.2_a +description: > + Tests that Intl.DateTimeFormat has a supportedLocalesOf property, + and it works as planned. +author: Roozbeh Pournader +---*/ + +var defaultLocale = new Intl.DateTimeFormat().resolvedOptions().locale; +var notSupported = 'zxx'; // "no linguistic content" +var requestedLocales = [defaultLocale, notSupported]; + +var supportedLocales; + +assert(Intl.DateTimeFormat.hasOwnProperty('supportedLocalesOf'), "Intl.DateTimeFormat doesn't have a supportedLocalesOf property."); + +supportedLocales = Intl.DateTimeFormat.supportedLocalesOf(requestedLocales); +assert.sameValue(supportedLocales.length, 1, 'The length of supported locales list is not 1.'); + +assert.sameValue(supportedLocales[0], defaultLocale, 'The default locale is not returned in the supported list.'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/browser.js b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/browser.js diff --git a/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/builtin.js b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/builtin.js new file mode 100644 index 0000000000..5af3ea6504 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/builtin.js @@ -0,0 +1,30 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +es5id: 12.2.2_L15 +description: > + Tests that Intl.DateTimeFormat.supportedLocalesOf meets the + requirements for built-in objects defined by the introduction of + chapter 17 of the ECMAScript Language Specification. +author: Norbert Lindenberg +includes: [isConstructor.js] +features: [Reflect.construct] +---*/ + +assert.sameValue(Object.prototype.toString.call(Intl.DateTimeFormat.supportedLocalesOf), "[object Function]", + "The [[Class]] internal property of a built-in function must be " + + "\"Function\"."); + +assert(Object.isExtensible(Intl.DateTimeFormat.supportedLocalesOf), + "Built-in objects must be extensible."); + +assert.sameValue(Object.getPrototypeOf(Intl.DateTimeFormat.supportedLocalesOf), Function.prototype); + +assert.sameValue(Intl.DateTimeFormat.supportedLocalesOf.hasOwnProperty("prototype"), false, + "Built-in functions that aren't constructors must not have a prototype property."); + +assert.sameValue(isConstructor(Intl.DateTimeFormat.supportedLocalesOf), false, + "Built-in functions don't implement [[Construct]] unless explicitly specified."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/length.js b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/length.js new file mode 100644 index 0000000000..728265c107 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/length.js @@ -0,0 +1,33 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.supportedlocalesof +description: > + Intl.DateTimeFormat.supportedLocalesOf.length is 1. +info: | + Intl.DateTimeFormat.supportedLocalesOf ( locales [ , options ] ) + + 17 ECMAScript Standard Built-in Objects: + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + Unless otherwise specified, the length property of a built-in function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. + +includes: [propertyHelper.js] +---*/ + +assert.sameValue(Intl.DateTimeFormat.supportedLocalesOf.length, 1); + +verifyNotEnumerable(Intl.DateTimeFormat.supportedLocalesOf, "length"); +verifyNotWritable(Intl.DateTimeFormat.supportedLocalesOf, "length"); +verifyConfigurable(Intl.DateTimeFormat.supportedLocalesOf, "length"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/name.js b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/name.js new file mode 100644 index 0000000000..1575c0d168 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/name.js @@ -0,0 +1,28 @@ +// Copyright (C) 2016 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-Intl.DateTimeFormat.supportedLocalesOf +description: > + Intl.DateTimeFormat.supportedLocalesOf.name is "supportedLocalesOf". +info: | + 12.3.2 Intl.DateTimeFormat.supportedLocalesOf (locales [ , options ]) + + 17 ECMAScript Standard Built-in Objects: + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +---*/ + +assert.sameValue(Intl.DateTimeFormat.supportedLocalesOf.name, "supportedLocalesOf"); + +verifyNotEnumerable(Intl.DateTimeFormat.supportedLocalesOf, "name"); +verifyNotWritable(Intl.DateTimeFormat.supportedLocalesOf, "name"); +verifyConfigurable(Intl.DateTimeFormat.supportedLocalesOf, "name"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/prop-desc.js b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/prop-desc.js new file mode 100644 index 0000000000..3a81c9f952 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/prop-desc.js @@ -0,0 +1,31 @@ +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl.datetimeformat.supportedlocalesof +description: > + "supportedLocalesOf" property of Intl.DateTimeFormat. +info: | + Intl.DateTimeFormat.supportedLocalesOf ( locales [ , options ] ) + + 7 Requirements for Standard Built-in ECMAScript Objects + + Unless specified otherwise in this document, the objects, functions, and constructors + described in this standard are subject to the generic requirements and restrictions + specified for standard built-in ECMAScript objects in the ECMAScript 2018 Language + Specification, 9th edition, clause 17, or successor. + + 17 ECMAScript Standard Built-in Objects: + + Every other data property described in clauses 18 through 26 and in Annex B.2 has the + attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } + unless otherwise specified. + +includes: [propertyHelper.js] +---*/ + +verifyNotEnumerable(Intl.DateTimeFormat, "supportedLocalesOf"); +verifyWritable(Intl.DateTimeFormat, "supportedLocalesOf"); +verifyConfigurable(Intl.DateTimeFormat, "supportedLocalesOf"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/shell.js b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/shell.js new file mode 100644 index 0000000000..54371b7789 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/shell.js @@ -0,0 +1,19 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +---*/ + +function isConstructor(f) { + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} diff --git a/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/taint-Object-prototype.js b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/taint-Object-prototype.js new file mode 100644 index 0000000000..47ed85a18c --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/supportedLocalesOf/taint-Object-prototype.js @@ -0,0 +1,16 @@ +// Copyright 2013 Mozilla Corporation. All rights reserved. +// This code is governed by the license found in the LICENSE file. + +/*--- +es5id: 12.2.2_b +description: > + Tests that Intl.DateTimeFormat.supportedLocalesOf doesn't access + arguments that it's not given. +author: Norbert Lindenberg +includes: [testIntl.js] +---*/ + +taintDataProperty(Object.prototype, "1"); +new Intl.DateTimeFormat("und"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-date-time-components.js b/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-date-time-components.js new file mode 100644 index 0000000000..a05e77b80e --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-date-time-components.js @@ -0,0 +1,18 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 12.1.1_22 +description: > + Tests that the behavior of a Record is not affected by + adversarial changes to Object.prototype. +author: Norbert Lindenberg +includes: [testIntl.js] +---*/ + +taintProperties(["weekday", "era", "year", "month", "day", "hour", "minute", "second", "timeZone"]); + +var locale = new Intl.DateTimeFormat(undefined, {localeMatcher: "lookup"}).resolvedOptions().locale; +assert(isCanonicalizedStructurallyValidLanguageTag(locale), "DateTimeFormat returns invalid locale " + locale + "."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-dayPeriod.js b/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-dayPeriod.js new file mode 100644 index 0000000000..a0f21acc24 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-dayPeriod.js @@ -0,0 +1,19 @@ +// |reftest| skip-if(release_or_beta) -- Intl.DateTimeFormat-dayPeriod is not released yet +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Tests that the behavior of a Record is not affected by + adversarial changes to Object.prototype. +includes: [testIntl.js] +features: [Intl.DateTimeFormat-dayPeriod] +---*/ + +taintProperties(["dayPeriod"]); + +var locale = new Intl.DateTimeFormat(undefined, {localeMatcher: "lookup"}).resolvedOptions().locale; +assert(isCanonicalizedStructurallyValidLanguageTag(locale), "DateTimeFormat returns invalid locale " + locale + "."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-fractionalSecondDigits.js b/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-fractionalSecondDigits.js new file mode 100644 index 0000000000..6b7836e1c8 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype-fractionalSecondDigits.js @@ -0,0 +1,18 @@ +// Copyright 2019 Google Inc. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-initializedatetimeformat +description: > + Tests that the behavior of a Record is not affected by + adversarial changes to Object.prototype. +includes: [testIntl.js] +features: [Intl.DateTimeFormat-fractionalSecondDigits] +---*/ + +taintProperties(["fractionalSecondDigits"]); + +var locale = new Intl.DateTimeFormat(undefined, {localeMatcher: "lookup"}).resolvedOptions().locale; +assert(isCanonicalizedStructurallyValidLanguageTag(locale), "DateTimeFormat returns invalid locale " + locale + "."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype.js b/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype.js new file mode 100644 index 0000000000..5dd7b61535 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/taint-Object-prototype.js @@ -0,0 +1,18 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 12.1.1_5 +description: > + Tests that the behavior of a Record is not affected by + adversarial changes to Object.prototype. +author: Norbert Lindenberg +includes: [testIntl.js] +---*/ + +taintProperties(["localeMatcher"]); + +var locale = new Intl.DateTimeFormat(undefined, {localeMatcher: "lookup"}).resolvedOptions().locale; +assert(isCanonicalizedStructurallyValidLanguageTag(locale), "DateTimeFormat returns invalid locale " + locale + "."); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/test-option-date-time-components.js b/js/src/tests/test262/intl402/DateTimeFormat/test-option-date-time-components.js new file mode 100644 index 0000000000..a0e0a16dc7 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/test-option-date-time-components.js @@ -0,0 +1,17 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 12.1.1_23 +description: > + Tests that the options for the date and time components are + processed correctly. +author: Norbert Lindenberg +includes: [testIntl.js] +---*/ + +getDateTimeComponents().forEach(function (component) { + testOption(Intl.DateTimeFormat, component, "string", getDateTimeComponentValues(component), undefined, {isILD: true}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/test-option-formatMatcher.js b/js/src/tests/test262/intl402/DateTimeFormat/test-option-formatMatcher.js new file mode 100644 index 0000000000..41c25d6e99 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/test-option-formatMatcher.js @@ -0,0 +1,13 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 12.1.1_25 +description: Tests that the option formatMatcher is processed correctly. +author: Norbert Lindenberg +includes: [testIntl.js] +---*/ + +testOption(Intl.DateTimeFormat, "formatMatcher", "string", ["basic", "best fit"], "best fit", {noReturn: true}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/test-option-hour12.js b/js/src/tests/test262/intl402/DateTimeFormat/test-option-hour12.js new file mode 100644 index 0000000000..c6a4124bf9 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/test-option-hour12.js @@ -0,0 +1,16 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 12.1.1_18 +description: Tests that the option hour12 is processed correctly. +author: Norbert Lindenberg +includes: [testIntl.js] +---*/ + +testOption(Intl.DateTimeFormat, "hour12", "boolean", undefined, undefined, + {extra: {any: {hour: "numeric", minute: "numeric"}}}); +testOption(Intl.DateTimeFormat, "hour12", "boolean", undefined, undefined, + {noReturn: true}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/test-option-localeMatcher.js b/js/src/tests/test262/intl402/DateTimeFormat/test-option-localeMatcher.js new file mode 100644 index 0000000000..6adf184682 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/test-option-localeMatcher.js @@ -0,0 +1,13 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 12.1.1_6 +description: Tests that the option localeMatcher is processed correctly. +author: Norbert Lindenberg +includes: [testIntl.js] +---*/ + +testOption(Intl.DateTimeFormat, "localeMatcher", "string", ["lookup", "best fit"], "best fit", {noReturn: true}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/this-value-ignored.js b/js/src/tests/test262/intl402/DateTimeFormat/this-value-ignored.js new file mode 100644 index 0000000000..e96110d1ca --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/this-value-ignored.js @@ -0,0 +1,37 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-intl-datetimeformat-constructor +description: > + Tests that the this-value is ignored in DateTimeFormat, if the this-value + isn't a DateTimeFormat instance. +author: Norbert Lindenberg +includes: [testIntl.js] +---*/ + +testWithIntlConstructors(function (Constructor) { + if (Constructor === Intl.DateTimeFormat) + return; + + var obj, newObj; + + // variant 1: use constructor in a "new" expression + obj = new Constructor(); + newObj = Intl.DateTimeFormat.call(obj); + assert.notSameValue(obj, newObj, "DateTimeFormat object created with \"new\" was not ignored as this-value."); + + // variant 2: use constructor as a function + if (Constructor !== Intl.Collator && + Constructor !== Intl.NumberFormat && + Constructor !== Intl.DateTimeFormat) + { + // Newer Intl constructors are not callable as a function. + return; + } + obj = Constructor(); + newObj = Intl.DateTimeFormat.call(obj); + assert.notSameValue(obj, newObj, "DateTimeFormat object created with constructor as function was not ignored as this-value."); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/timezone-canonicalized.js b/js/src/tests/test262/intl402/DateTimeFormat/timezone-canonicalized.js new file mode 100644 index 0000000000..e7e28cd0e6 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/timezone-canonicalized.js @@ -0,0 +1,37 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 6.4_c +description: > + Tests that additional time zone names, if accepted, are handled + correctly. +author: Norbert Lindenberg +---*/ + +// canonicalization specified in conformance clause +var additionalTimeZoneNames = { + "Etc/GMT": "UTC", + "Greenwich": "UTC", + "PRC": "Asia/Shanghai", + "AmErIcA/LoS_aNgElEs": "America/Los_Angeles", + "etc/gmt+7": "Etc/GMT+7" +}; + +Object.getOwnPropertyNames(additionalTimeZoneNames).forEach(function (name) { + var format, error; + try { + format = new Intl.DateTimeFormat([], {timeZone: name}); + } catch (e) { + error = e; + } + if (error === undefined) { + var actual = format.resolvedOptions().timeZone; + var expected = additionalTimeZoneNames[name]; + assert.sameValue(actual, expected, "Time zone name " + name + " was accepted, but incorrectly canonicalized."); + } else { + assert(error instanceof RangeError, "Time zone name " + name + " was rejected with wrong error " + error.name + "."); + } +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/timezone-invalid.js b/js/src/tests/test262/intl402/DateTimeFormat/timezone-invalid.js new file mode 100644 index 0000000000..f42ffd0201 --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/timezone-invalid.js @@ -0,0 +1,28 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 6.4_b +description: Tests that invalid time zone names are not accepted. +author: Norbert Lindenberg +---*/ + +var invalidTimeZoneNames = [ + "", + "MEZ", // localized abbreviation + "Pacific Time", // localized long form + "cnsha", // BCP 47 time zone code + "invalid", // as the name says + "Europe/İstanbul", // non-ASCII letter + "asıa/baku", // non-ASCII letter + "europe/brußels" // non-ASCII letter +]; + +invalidTimeZoneNames.forEach(function (name) { + // this must throw an exception for an invalid time zone name + assert.throws(RangeError, function() { + var format = new Intl.DateTimeFormat(["de-de"], {timeZone: name}); + }, "Invalid time zone name " + name + " was not rejected."); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/intl402/DateTimeFormat/timezone-utc.js b/js/src/tests/test262/intl402/DateTimeFormat/timezone-utc.js new file mode 100644 index 0000000000..f27d109b1a --- /dev/null +++ b/js/src/tests/test262/intl402/DateTimeFormat/timezone-utc.js @@ -0,0 +1,21 @@ +// Copyright 2012 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es5id: 6.4_a +description: Tests that valid time zone names are accepted. +author: Norbert Lindenberg +---*/ + +var validTimeZoneNames = [ + "UTC", + "utc" // time zone names are case-insensitive +]; + +validTimeZoneNames.forEach(function (name) { + // this must not throw an exception for a valid time zone name + var format = new Intl.DateTimeFormat(["de-de"], {timeZone: name}); + assert.sameValue(format.resolvedOptions().timeZone, name.toUpperCase(), "Time zone name " + name + " was not correctly accepted."); +}); + +reportCompare(0, 0); |