Skip to content

Commit

Permalink
Intl.DurationFormat update coverage (#3501)
Browse files Browse the repository at this point in the history
* constructor tests coverage
* add localeMatcher tests
* add styles and numbering system tests
* re-organize folder and files structure
  • Loading branch information
romulocintra committed May 3, 2022
1 parent 7099acc commit 28455b1
Show file tree
Hide file tree
Showing 27 changed files with 569 additions and 0 deletions.
17 changes: 17 additions & 0 deletions test/intl402/DurationFormat/constructor-locales-invalid.js
@@ -0,0 +1,17 @@
// Copyright 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-Intl.DurationFormat
description: Checks error cases for the locales argument to the DurationFormat constructor.
info: |
Intl.DurationFormat ( [ locales [ , options ] ] )
(...)
3. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).
includes: [testIntl.js]
features: [Intl.DurationFormat]
---*/

for (const [locales, expectedError] of getInvalidLocaleArguments()) {
assert.throws(expectedError, function() { new Intl.DurationFormat(locales) })
}
34 changes: 34 additions & 0 deletions test/intl402/DurationFormat/constructor-locales-valid.js
@@ -0,0 +1,34 @@
// Copyright 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-Intl.DurationFormat
description: Checks cases for the locales argument to the DurationFormat constructor.
info: |
Intl.DurationFormat ( [ locales [ , options ] ] )
(...)
3. Let _requestedLocales_ be ? CanonicalizeLocaleList(_locales_).
features: [Intl.DurationFormat]
---*/

const defaultLocale = new Intl.DurationFormat().resolvedOptions().locale;

const matchers = ["lookup", "best fit"]

const tests = [
[undefined, defaultLocale, "undefined"],
["EN", "en", "Single value"],
[[], defaultLocale, "Empty array"],
[["en", "EN"], "en", "Duplicate value (canonical first)"],
[["EN", "en"], "en", "Duplicate value (canonical last)"],
[{ 0: "DE", length: 0 }, defaultLocale, "Object with zero length"],
[{ 0: "DE", length: 1 }, "de", "Object with length"],
];


for (const [locales, expected, name] of tests) {
matchers.forEach((matcher)=>{
const drf = new Intl.DurationFormat(locales, {localeMatcher: matcher});
assert.sameValue(drf.resolvedOptions().locale, expected, name);
});
};
32 changes: 32 additions & 0 deletions test/intl402/DurationFormat/constructor-options-defaults.js
@@ -0,0 +1,32 @@
// Copyright 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-Intl.DurationFormat
description: Checks handling of valid options for the DurationFormat constructor.
info: |
Intl.DurationFormat ( [ locales [ , options ] ] )
(...)
17. For each row in Table 1, except the header row, in table order, do
a. Let styleSlot be the Style Slot value.
b. Let displaySlot be the Display Slot value.
c. Let unit be the Unit value.
d. Let valueList be the Values value.
e. Let digitalBase be the Digital Default value.
f. Let unitOptions be ? GetUnitOptions(unit, options, style, valueList, digitalBase, prevStyle).
g. Set durationFormat.[[<styleSlot>]] to unitOptions.[[Style]].
h. Set durationFormat.[[<displaySlot>]] to unitOptions.[[Display]].
features: [Intl.DurationFormat]
includes: [testIntl.js]
---*/

testOption( Intl.DurationFormat, "years", "string", ["long", "short", "narrow"], "narrow");
testOption( Intl.DurationFormat, "months", "string", ["long", "short", "narrow"], "narrow");
testOption( Intl.DurationFormat, "weeks", "string", ["long", "short", "narrow"], "narrow");
testOption( Intl.DurationFormat, "days", "string", ["long", "short", "narrow", "numeric", "2-digit"], "numeric");
testOption( Intl.DurationFormat, "hours", "string", ["long", "short", "narrow", "numeric", "2-digit"], "numeric");
testOption( Intl.DurationFormat, "minutes", "string", ["long", "short", "narrow", "numeric", "2-digit"], "numeric");
testOption( Intl.DurationFormat, "milliseconds", "string", ["long", "short", "narrow", "numeric", "2-digit"], "numeric");
testOption( Intl.DurationFormat, "microseconds", "string", ["long", "short", "narrow", "numeric", "2-digit"], "numeric");
testOption( Intl.DurationFormat, "nanoseconds", "string", ["long", "short", "narrow", "numeric", "2-digit"], "numeric");

@@ -0,0 +1,23 @@
// Copyright 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-Intl.DurationFormat
description: Tests that the option localeMatcher is processed correctly.
info: |
Intl.DurationFormat ( [ locales [ , options ] ] )
(...)
18. Set durationFormat.[[FractionalDigits]] to ? GetNumberOption(options, "fractionalDigits", 0, 9, undefined).
features: [Intl.DurationFormat]
---*/

const invalidOptions = [
-10,
10
];

for (const fractionalDigits of invalidOptions) {
assert.throws(RangeError, function() {
new Intl.DurationFormat("en", { fractionalDigits });
}, `new Intl.DurationFormat("en", {fractionalDigits: "${fractionalDigits}"}) throws RangeError`);
}
@@ -0,0 +1,25 @@
// Copyright 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-Intl.DurationFormat
description: Tests that the option localeMatcher is processed correctly.
info: |
Intl.DurationFormat ( [ locales [ , options ] ] )
(...)
18. Set durationFormat.[[FractionalDigits]] to ? GetNumberOption(options, "fractionalDigits", 0, 9, undefined).
features: [Intl.DurationFormat]
---*/

const validOptions = [
undefined,
0,
1,
5,
9
];

for (const fractionalDigits of validOptions) {
const obj = new Intl.DurationFormat("en", {fractionalDigits});
assert.sameValue(obj.resolvedOptions().fractionalDigits, fractionalDigits, `${fractionalDigits} is supported by DurationFormat`);
}
16 changes: 16 additions & 0 deletions test/intl402/DurationFormat/constructor-options-invalid.js
@@ -0,0 +1,16 @@
// Copyright 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-Intl.DurationFormat
description: Checks handling of a null options argument to the DurationFormat constructor.
info: |
Intl.DurationFormat ( [ locales [ , options ] ] )
(...)
4. Let options be GetOptionsObject(options).
features: [Intl.DurationFormat]
---*/

assert.sameValue(typeof Intl.DurationFormat, "function");

assert.throws(TypeError, function() { new Intl.DurationFormat([], null) })
@@ -0,0 +1,30 @@
// Copyright 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-Intl.DurationFormat
description: Checks handling of invalid value for the localeMatcher option to the DurationFormat constructor.
info: |
Intl.DurationFormat ( [ locales [ , options ] ] )
(...)
5. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit").
features: [Intl.DurationFormat]
---*/

const invalidOptions = [
null,
1,
"",
"Lookup",
"LOOKUP",
"lookup\0",
"Best fit",
"BEST FIT",
"best\u00a0fit",
];

for (const localeMatcher of invalidOptions) {
assert.throws(RangeError, function() {
new Intl.DurationFormat([], { localeMatcher });
}, `${localeMatcher} is an invalid localeMatcher option value`);
}
@@ -0,0 +1,15 @@
// Copyright 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-Intl.DurationFormat
description: Tests that the option localeMatcher is processed correctly.
info: |
Intl.DurationFormat ( [ locales [ , options ] ] )
(...)
5. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit").
features: [Intl.DurationFormat]
includes: [testIntl.js]
---*/

testOption(Intl.DurationFormat, "localeMatcher", "string", ["lookup", "best fit"], "best fit", {noReturn: true});
@@ -0,0 +1,36 @@
// Copyright 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-Intl.DurationFormat
description: >
Checks error cases for the options argument to the DurationFormat constructor.
info: |
Intl.DurationFormat ( [ locales [ , options ] ] )
(...)
6. Let numberingSystem be ? GetOption(options, "numberingSystem", "string", undefined, undefined).
7. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
features: [Intl.DurationFormat]
---*/

const invalidOptions = [
"",
"a",
"ab",
"abcdefghi",
"abc-abcdefghi",
"!invalid!",
"-latn-",
"latn-",
"latn--",
"latn-ca",
"latn-ca-",
"latn-ca-gregory",
"latné",
"latn编号",
];
for (const numberingSystem of invalidOptions) {
assert.throws(RangeError, function() {
new Intl.DurationFormat('en', {numberingSystem});
}, `new Intl.DurationFormat("en", {numberingSystem: "${numberingSystem}"}) throws RangeError`);
}
@@ -0,0 +1,21 @@
// Copyright 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-Intl.DurationFormat
description: >
Checks error cases for the options argument to the DurationFormat constructor.
info: |
Intl.DurationFormat ( [ locales [ , options ] ] )
(...)
6. Let numberingSystem be ? GetOption(options, "numberingSystem", "string", undefined, undefined).
7. If numberingSystem does not match the Unicode Locale Identifier type nonterminal, throw a RangeError exception.
features: [Intl.DurationFormat]
---*/

const numberingSystems = Intl.supportedValuesOf("numberingSystem");

for (const numberingSystem of numberingSystems) {
const obj = new Intl.DurationFormat("en", {numberingSystem});
assert.sameValue(obj.resolvedOptions().numberingSystem, numberingSystem, `${numberingSystem} is supported by DurationFormat`);
}
41 changes: 41 additions & 0 deletions test/intl402/DurationFormat/constructor-options-order.js
@@ -0,0 +1,41 @@
// Copyright 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-Intl.DurationFormat
description: Checks the order of operations on the options argument to the DurationFormat constructor.
info: |
Intl.DurationFormat ( [ locales [ , options ] ] )
(...)
5. Let matcher be ? GetOption(options, "localeMatcher", "string", « "lookup", "best fit" », "best fit").
6. Let numberingSystem be ? GetOption(options, "numberingSystem", "string", undefined, undefined).
13. Let style be ? GetOption(options, "style", "string", « "long", "short", "narrow", "digital" », "long").
includes: [compareArray.js]
features: [Intl.DurationFormat]
---*/

var actual = [];

const options = {
get localeMatcher() {
actual.push("localeMatcher");
return undefined;
},
get numberingSystem() {
actual.push("numberingSystem");
return undefined;
},
get style() {
actual.push("style");
return undefined;
},
};

const expected = [
"localeMatcher",
"numberingSystem",
"style"
];

let nf = new Intl.DurationFormat(undefined, options);
assert.compareArray(actual, expected);
37 changes: 37 additions & 0 deletions test/intl402/DurationFormat/constructor-options-style-invalid.js
@@ -0,0 +1,37 @@
// Copyright 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-Intl.DurationFormat
description: Checks handling of invalid value for the style option to the DurationFormat constructor.
info: |
InitializeDurationFormat (DurationFormat, locales, options)
(...)
13. Let style be ? GetOption(options, "style", "string", « "long", "short", "narrow", "digital" », "long").
14. Set durationFormat.[[Style]] to style.
features: [Intl.DurationFormat]
---*/

const invalidOptions = [
null,
1,
"",
"Long",
"LONG",
"long\0",
"Short",
"SHORT",
"short\0",
"Narrow",
"NARROW",
"narrow\0",
"Digital",
"DIGITAL",
"digital\0",
];

for (const invalidOption of invalidOptions) {
assert.throws(RangeError, function() {
new Intl.DurationFormat([], {"style": invalidOption});
}, `${invalidOption} is an invalid style option value`);
}
31 changes: 31 additions & 0 deletions test/intl402/DurationFormat/constructor-options-style-valid.js
@@ -0,0 +1,31 @@
// Copyright 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-Intl.DurationFormat
description: Checks handling of valid values for the style option to the DurationFormat constructor.
info: |
InitializeDurationFormat (DurationFormat, locales, options)
(...)
13. Let style be ? GetOption(options, "style", "string", « "long", "short", "narrow", "digital" », "long").
14. Set durationFormat.[[Style]] to style.
features: [Intl.DurationFormat]
---*/

const validOptions = [
[undefined, "long"],
["long", "long"],
["short", "short"],
["narrow", "narrow"],
["digital", "digital"],
[{ toString() { return "short"; } }, "short"],
[{ toString() { return "long"; } }, "long"],
[{ toString() { return "narrow"; } }, "narrow"],
[{ toString() { return "digital"; } }, "digital"],
];

for (const [validOption, expected] of validOptions) {
const df = new Intl.DurationFormat([], {"style": validOption});
const resolvedOptions = df.resolvedOptions();
assert.sameValue(resolvedOptions.style, expected);
}
File renamed without changes.
File renamed without changes.
27 changes: 27 additions & 0 deletions test/intl402/DurationFormat/newtarget-undefined.js
@@ -0,0 +1,27 @@
// Copyright 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-Intl.DurationFormat
description: >
Verifies the NewTarget check for Intl.DurationFormat.
info: |
Intl.DurationFormat ([ locales [ , options ]])
(...)
1. If NewTarget is undefined, throw a TypeError exception.
features: [Intl.DurationFormat]
---*/

assert.sameValue(typeof Intl.DurationFormat, "function");

assert.throws(TypeError, function() {
Intl.DurationFormat();
});

assert.throws(TypeError, function() {
Intl.DurationFormat("en");
});

assert.throws(TypeError, function() {
Intl.DurationFormat("not-valid-tag");
});
File renamed without changes.
File renamed without changes.

0 comments on commit 28455b1

Please sign in to comment.