[INTL] Implement Intl.DateTimeFormat.prototype.resolvedOptions ()
[WebKit.git] / LayoutTests / js / script-tests / intl-datetimeformat.js
1 description("This test checks the behavior of Intl.DateTimeFormat as described in the ECMAScript Internationalization API Specification (ECMA-402 2.0).");
2
3 // 12.1 The Intl.DateTimeFormat Constructor
4
5 // The Intl.DateTimeFormat constructor is a standard built-in property of the Intl object.
6 shouldBeType("Intl.DateTimeFormat", "Function");
7
8 // 12.1.2 Intl.DateTimeFormat([ locales [, options]])
9 shouldBeType("Intl.DateTimeFormat()", "Intl.DateTimeFormat");
10 shouldBeType("Intl.DateTimeFormat.call({})", "Intl.DateTimeFormat");
11 shouldBeType("new Intl.DateTimeFormat()", "Intl.DateTimeFormat");
12
13 // Subclassable
14 var classPrefix = "class DerivedDateTimeFormat extends Intl.DateTimeFormat {};";
15 shouldBeTrue(classPrefix + "(new DerivedDateTimeFormat) instanceof DerivedDateTimeFormat");
16 shouldBeTrue(classPrefix + "(new DerivedDateTimeFormat) instanceof Intl.DateTimeFormat");
17 shouldBeTrue(classPrefix + "new DerivedDateTimeFormat().format(0).length > 0");
18 shouldBeTrue(classPrefix + "Object.getPrototypeOf(new DerivedDateTimeFormat) === DerivedDateTimeFormat.prototype");
19 shouldBeTrue(classPrefix + "Object.getPrototypeOf(Object.getPrototypeOf(new DerivedDateTimeFormat)) === Intl.DateTimeFormat.prototype");
20
21 // 12.2 Properties of the Intl.DateTimeFormat Constructor
22
23 // length property (whose value is 0)
24 shouldBe("Intl.DateTimeFormat.length", "0");
25
26 // 12.2.1 Intl.DateTimeFormat.prototype
27
28 // This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
29 shouldBeFalse("Object.getOwnPropertyDescriptor(Intl.DateTimeFormat, 'prototype').writable");
30 shouldBeFalse("Object.getOwnPropertyDescriptor(Intl.DateTimeFormat, 'prototype').enumerable");
31 shouldBeFalse("Object.getOwnPropertyDescriptor(Intl.DateTimeFormat, 'prototype').configurable");
32
33 // 12.2.2 Intl.DateTimeFormat.supportedLocalesOf (locales [, options ])
34
35 // The value of the length property of the supportedLocalesOf method is 1.
36 shouldBe("Intl.DateTimeFormat.supportedLocalesOf.length", "1");
37
38 // Returns SupportedLocales
39 shouldBeType("Intl.DateTimeFormat.supportedLocalesOf()", "Array");
40 // Doesn't care about `this`.
41 shouldBe("Intl.DateTimeFormat.supportedLocalesOf.call(null, 'en')", "[ 'en' ]");
42 shouldBe("Intl.DateTimeFormat.supportedLocalesOf.call({}, 'en')", "[ 'en' ]");
43 shouldBe("Intl.DateTimeFormat.supportedLocalesOf.call(1, 'en')", "[ 'en' ]");
44 // Ignores non-object, non-string list.
45 shouldBe("Intl.DateTimeFormat.supportedLocalesOf(9)", "[]");
46 // Makes an array of tags.
47 shouldBe("Intl.DateTimeFormat.supportedLocalesOf('en')", "[ 'en' ]");
48 // Handles array-like objects with holes.
49 shouldBe("Intl.DateTimeFormat.supportedLocalesOf({ length: 4, 1: 'en', 0: 'es', 3: 'de' })", "[ 'es', 'en', 'de' ]");
50 // Deduplicates tags.
51 shouldBe("Intl.DateTimeFormat.supportedLocalesOf([ 'en', 'pt', 'en', 'es' ])", "[ 'en', 'pt', 'es' ]");
52 // Canonicalizes tags.
53 shouldBe("Intl.DateTimeFormat.supportedLocalesOf('En-laTn-us-variant2-variant1-1abc-U-ko-tRue-A-aa-aaa-x-RESERVED')", "[ 'en-Latn-US-variant2-variant1-1abc-a-aa-aaa-u-ko-true-x-reserved' ]");
54 // Replaces outdated tags.
55 shouldBe("Intl.DateTimeFormat.supportedLocalesOf('no-bok')", "[ 'nb' ]");
56 // Doesn't throw, but ignores private tags.
57 shouldBe("Intl.DateTimeFormat.supportedLocalesOf('x-some-thing')", "[]");
58 // Throws on problems with length, get, or toString.
59 shouldThrow("Intl.DateTimeFormat.supportedLocalesOf(Object.create(null, { length: { get() { throw Error('a') } } }))", "'Error: a'");
60 shouldThrow("Intl.DateTimeFormat.supportedLocalesOf(Object.create(null, { length: { value: 1 }, 0: { get() { throw Error('b') } } }))", "'Error: b'");
61 shouldThrow("Intl.DateTimeFormat.supportedLocalesOf([ { toString() { throw Error('c') } } ])", "'Error: c'");
62 // Throws on bad tags.
63 shouldThrow("Intl.DateTimeFormat.supportedLocalesOf([ 5 ])", "'TypeError: locale value must be a string or object'");
64 shouldThrow("Intl.DateTimeFormat.supportedLocalesOf('')", "'RangeError: invalid language tag: '");
65 shouldThrow("Intl.DateTimeFormat.supportedLocalesOf('a')", "'RangeError: invalid language tag: a'");
66 shouldThrow("Intl.DateTimeFormat.supportedLocalesOf('abcdefghij')", "'RangeError: invalid language tag: abcdefghij'");
67 shouldThrow("Intl.DateTimeFormat.supportedLocalesOf('#$')", "'RangeError: invalid language tag: #$'");
68 shouldThrow("Intl.DateTimeFormat.supportedLocalesOf('en-@-abc')", "'RangeError: invalid language tag: en-@-abc'");
69 shouldThrow("Intl.DateTimeFormat.supportedLocalesOf('en-u')", "'RangeError: invalid language tag: en-u'");
70 shouldThrow("Intl.DateTimeFormat.supportedLocalesOf('en-u-kn-true-u-ko-true')", "'RangeError: invalid language tag: en-u-kn-true-u-ko-true'");
71 shouldThrow("Intl.DateTimeFormat.supportedLocalesOf('en-x')", "'RangeError: invalid language tag: en-x'");
72 shouldThrow("Intl.DateTimeFormat.supportedLocalesOf('en-*')", "'RangeError: invalid language tag: en-*'");
73 shouldThrow("Intl.DateTimeFormat.supportedLocalesOf('en-')", "'RangeError: invalid language tag: en-'");
74 shouldThrow("Intl.DateTimeFormat.supportedLocalesOf('en--US')", "'RangeError: invalid language tag: en--US'");
75
76 // 12.3 Properties of the Intl.DateTimeFormat Prototype Object
77
78 // The value of Intl.DateTimeFormat.prototype.constructor is %DateTimeFormat%.
79 shouldBe("Intl.DateTimeFormat.prototype.constructor", "Intl.DateTimeFormat");
80
81 // 12.3.3 Intl.DateTimeFormat.prototype.format
82
83 // This named accessor property returns a function that formats a date according to the effective locale and the formatting options of this DateTimeFormat object.
84 shouldBeType("Intl.DateTimeFormat.prototype.format", "Function");
85
86 // The value of the [[Get]] attribute is a function
87 shouldBeType("Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, 'format').get", "Function");
88
89 // The value of the [[Set]] attribute is undefined.
90 shouldBe("Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, 'format').set", "undefined");
91
92 // Match Firefox where unspecifed.
93 shouldBeFalse("Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, 'format').enumerable");
94 shouldBeTrue("Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, 'format').configurable");
95
96 // The value of F’s length property is 1.
97 shouldBe("Intl.DateTimeFormat.prototype.format.length", "1");
98
99 // Throws on non-DateTimeFormat this.
100 shouldThrow("Object.defineProperty({}, 'format', Object.getOwnPropertyDescriptor(Intl.DateTimeFormat.prototype, 'format')).format", "'TypeError: Intl.DateTimeFormat.prototype.format called on value that\\'s not an object initialized as a DateTimeFormat'");
101
102 // The format function is unique per instance.
103 shouldBeTrue("Intl.DateTimeFormat.prototype.format !== Intl.DateTimeFormat().format");
104 shouldBeTrue("new Intl.DateTimeFormat().format !== new Intl.DateTimeFormat().format");
105
106 // 12.3.4 DateTime Format Functions
107
108 // 1. Let dtf be the this value.
109 // 2. Assert: Type(dtf) is Object and dtf has an [[initializedDateTimeFormat]] internal slot whose value is true.
110 // This should not be reachable, since format is bound to an initialized datetimeformat.
111
112 // 3. If date is not provided or is undefined, then
113 // a. Let x be %Date_now%().
114 // 4. Else
115 // a. Let x be ToNumber(date).
116 // b. ReturnIfAbrupt(x).
117 shouldThrow("Intl.DateTimeFormat.prototype.format({ valueOf() { throw Error('4b') } })", "'Error: 4b'");
118
119 // 12.3.4 FormatDateTime abstract operation
120
121 // 1. If x is not a finite Number, then throw a RangeError exception.
122 shouldThrow("Intl.DateTimeFormat.prototype.format(Infinity)", "'RangeError: date value is not finite in DateTimeFormat format()'");
123
124 // Format is bound, so calling with alternate "this" has no effect.
125 shouldBe("Intl.DateTimeFormat.prototype.format.call(null, 0)", "Intl.DateTimeFormat().format(0)");
126 shouldBe("Intl.DateTimeFormat.prototype.format.call(Intl.DateTimeFormat('ar'), 0)", "Intl.DateTimeFormat().format(0)");
127 shouldBe("Intl.DateTimeFormat.prototype.format.call(5, 0)", "Intl.DateTimeFormat().format(0)");
128 shouldBe("new Intl.DateTimeFormat().format.call(null, 0)", "Intl.DateTimeFormat().format(0)");
129 shouldBe("new Intl.DateTimeFormat().format.call(Intl.DateTimeFormat('ar'), 0)", "Intl.DateTimeFormat().format(0)");
130 shouldBe("new Intl.DateTimeFormat().format.call(5, 0)", "Intl.DateTimeFormat().format(0)");
131
132 // 12.3.5 Intl.DateTimeFormat.prototype.resolvedOptions ()
133
134 shouldBe("Intl.DateTimeFormat.prototype.resolvedOptions.length", "0");
135
136 // Returns a new object whose properties and attributes are set as if constructed by an object literal.
137 shouldBeType("Intl.DateTimeFormat.prototype.resolvedOptions()", "Object");
138
139 // The Intl.DateTimeFormat prototype object is itself an %DateTimeFormat% instance, whose internal slots are set as if it had been constructed by the expression Construct(%DateTimeFormat%).
140 shouldBe("Intl.DateTimeFormat.prototype.resolvedOptions().locale", "new Intl.DateTimeFormat().resolvedOptions().locale");
141 shouldBe("Intl.DateTimeFormat.prototype.resolvedOptions().timeZone", "new Intl.DateTimeFormat().resolvedOptions().timeZone");
142 shouldBe("Intl.DateTimeFormat.prototype.resolvedOptions().calendar", "new Intl.DateTimeFormat().resolvedOptions().calendar");
143 shouldBe("Intl.DateTimeFormat.prototype.resolvedOptions().numberingSystem", "new Intl.DateTimeFormat().resolvedOptions().numberingSystem");
144 shouldBe("Intl.DateTimeFormat.prototype.resolvedOptions().weekday", "new Intl.DateTimeFormat().resolvedOptions().weekday");
145 shouldBe("Intl.DateTimeFormat.prototype.resolvedOptions().era", "new Intl.DateTimeFormat().resolvedOptions().era");
146 shouldBe("Intl.DateTimeFormat.prototype.resolvedOptions().year", "new Intl.DateTimeFormat().resolvedOptions().year");
147 shouldBe("Intl.DateTimeFormat.prototype.resolvedOptions().month", "new Intl.DateTimeFormat().resolvedOptions().month");
148 shouldBe("Intl.DateTimeFormat.prototype.resolvedOptions().day", "new Intl.DateTimeFormat().resolvedOptions().day");
149 shouldBe("Intl.DateTimeFormat.prototype.resolvedOptions().hour", "new Intl.DateTimeFormat().resolvedOptions().hour");
150 shouldBe("Intl.DateTimeFormat.prototype.resolvedOptions().hour12", "new Intl.DateTimeFormat().resolvedOptions().hour12");
151 shouldBe("Intl.DateTimeFormat.prototype.resolvedOptions().minute", "new Intl.DateTimeFormat().resolvedOptions().minute");
152 shouldBe("Intl.DateTimeFormat.prototype.resolvedOptions().second", "new Intl.DateTimeFormat().resolvedOptions().second");
153 shouldBe("Intl.DateTimeFormat.prototype.resolvedOptions().timeZoneName", "new Intl.DateTimeFormat().resolvedOptions().timeZoneName");
154
155 // Returns a new object each time.
156 shouldBeFalse("Intl.DateTimeFormat.prototype.resolvedOptions() === Intl.DateTimeFormat.prototype.resolvedOptions()");
157
158 // Throws on non-DateTimeFormat this.
159 shouldThrow("Intl.DateTimeFormat.prototype.resolvedOptions.call(5)", "'TypeError: Intl.DateTimeFormat.prototype.resolvedOptions called on value that\\'s not an object initialized as a DateTimeFormat'");
160
161 shouldThrow("Intl.DateTimeFormat('$')", "'RangeError: invalid language tag: $'");
162 shouldNotThrow("Intl.DateTimeFormat('en', null)");
163
164 // Defaults to month, day, year.
165 shouldBe("Intl.DateTimeFormat('en').resolvedOptions().weekday", "undefined");
166 shouldBe("Intl.DateTimeFormat('en').resolvedOptions().era", "undefined");
167 shouldBe("Intl.DateTimeFormat('en').resolvedOptions().month", "'numeric'");
168 shouldBe("Intl.DateTimeFormat('en').resolvedOptions().day", "'numeric'");
169 shouldBe("Intl.DateTimeFormat('en').resolvedOptions().year", "'numeric'");
170 shouldBe("Intl.DateTimeFormat('en').resolvedOptions().hour", "undefined");
171 shouldBe("Intl.DateTimeFormat('en').resolvedOptions().hour12", "undefined");
172 shouldBe("Intl.DateTimeFormat('en').resolvedOptions().minute", "undefined");
173 shouldBe("Intl.DateTimeFormat('en').resolvedOptions().second", "undefined");
174 shouldBe("Intl.DateTimeFormat('en').resolvedOptions().timeZoneName", "undefined");
175
176 shouldThrow("Intl.DateTimeFormat('en', { localeMatcher: { toString() { throw 'nope' } } })", "'nope'");
177 shouldThrow("Intl.DateTimeFormat('en', { localeMatcher:'bad' })", '\'RangeError: localeMatcher must be either "lookup" or "best fit"\'');
178 shouldNotThrow("Intl.DateTimeFormat('en', { localeMatcher:'lookup' })");
179 shouldNotThrow("Intl.DateTimeFormat('en', { localeMatcher:'best fit' })");
180
181 shouldThrow("Intl.DateTimeFormat('en', { formatMatcher: { toString() { throw 'nope' } } })", "'nope'");
182 shouldThrow("Intl.DateTimeFormat('en', { formatMatcher:'bad' })", '\'RangeError: formatMatcher must be either "basic" or "best fit"\'');
183 shouldNotThrow("Intl.DateTimeFormat('en', { formatMatcher:'basic' })");
184 shouldNotThrow("Intl.DateTimeFormat('en', { formatMatcher:'best fit' })");
185
186 shouldThrow("Intl.DateTimeFormat('en', { timeZone: 'nowhere/bogus' })", "'RangeError: invalid time zone: nowhere/bogus'");
187 shouldThrow("Intl.DateTimeFormat('en', { timeZone: { toString() { throw 'nope' } } })", "'nope'");
188
189 // Time zone is case insensitive.
190 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'america/denver' }).resolvedOptions().timeZone", "'America/Denver'");
191 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'AMERICA/LOS_ANGELES' }).resolvedOptions().timeZone", "'America/Los_Angeles'");
192
193 // Default time zone is a valid canonical time zone.
194 shouldBe("Intl.DateTimeFormat('en', { timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone }).resolvedOptions().timeZone", "Intl.DateTimeFormat().resolvedOptions().timeZone");
195
196 // Time zone is canonicalized for obsolete links in IANA tz backward file.
197 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'America/Atka' }).resolvedOptions().timeZone", "'America/Adak'");
198 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'America/Ensenada' }).resolvedOptions().timeZone", "'America/Tijuana'");
199 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'America/Porto_Acre' }).resolvedOptions().timeZone", "'America/Rio_Branco'");
200 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'America/Shiprock' }).resolvedOptions().timeZone", "'America/Denver'");
201 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Antarctica/South_Pole' }).resolvedOptions().timeZone", "'Pacific/Auckland'");
202 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Asia/Ashkhabad' }).resolvedOptions().timeZone", "'Asia/Ashgabat'");
203 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Asia/Chongqing' }).resolvedOptions().timeZone", "'Asia/Shanghai'");
204 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Asia/Chungking' }).resolvedOptions().timeZone", "'Asia/Shanghai'");
205 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Asia/Dacca' }).resolvedOptions().timeZone", "'Asia/Dhaka'");
206 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Asia/Harbin' }).resolvedOptions().timeZone", "'Asia/Shanghai'");
207 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Asia/Kashgar' }).resolvedOptions().timeZone", "'Asia/Urumqi'");
208 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Asia/Macao' }).resolvedOptions().timeZone", "'Asia/Macau'");
209 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Asia/Tel_Aviv' }).resolvedOptions().timeZone", "'Asia/Jerusalem'");
210 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Asia/Thimbu' }).resolvedOptions().timeZone", "'Asia/Thimphu'");
211 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Asia/Ujung_Pandang' }).resolvedOptions().timeZone", "'Asia/Makassar'");
212 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Asia/Ulan_Bator' }).resolvedOptions().timeZone", "'Asia/Ulaanbaatar'");
213 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Australia/ACT' }).resolvedOptions().timeZone", "'Australia/Sydney'");
214 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Australia/Canberra' }).resolvedOptions().timeZone", "'Australia/Sydney'");
215 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Australia/LHI' }).resolvedOptions().timeZone", "'Australia/Lord_Howe'");
216 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Australia/NSW' }).resolvedOptions().timeZone", "'Australia/Sydney'");
217 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Australia/North' }).resolvedOptions().timeZone", "'Australia/Darwin'");
218 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Australia/Queensland' }).resolvedOptions().timeZone", "'Australia/Brisbane'");
219 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Australia/South' }).resolvedOptions().timeZone", "'Australia/Adelaide'");
220 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Australia/Tasmania' }).resolvedOptions().timeZone", "'Australia/Hobart'");
221 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Australia/Victoria' }).resolvedOptions().timeZone", "'Australia/Melbourne'");
222 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Australia/West' }).resolvedOptions().timeZone", "'Australia/Perth'");
223 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Australia/Yancowinna' }).resolvedOptions().timeZone", "'Australia/Broken_Hill'");
224 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Brazil/Acre' }).resolvedOptions().timeZone", "'America/Rio_Branco'");
225 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Brazil/DeNoronha' }).resolvedOptions().timeZone", "'America/Noronha'");
226 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Brazil/East' }).resolvedOptions().timeZone", "'America/Sao_Paulo'");
227 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Brazil/West' }).resolvedOptions().timeZone", "'America/Manaus'");
228 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Canada/Atlantic' }).resolvedOptions().timeZone", "'America/Halifax'");
229 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Canada/Central' }).resolvedOptions().timeZone", "'America/Winnipeg'");
230 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Canada/East-Saskatchewan' }).resolvedOptions().timeZone", "'America/Regina'");
231 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Canada/Eastern' }).resolvedOptions().timeZone", "'America/Toronto'");
232 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Canada/Mountain' }).resolvedOptions().timeZone", "'America/Edmonton'");
233 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Canada/Newfoundland' }).resolvedOptions().timeZone", "'America/St_Johns'");
234 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Canada/Pacific' }).resolvedOptions().timeZone", "'America/Vancouver'");
235 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Canada/Saskatchewan' }).resolvedOptions().timeZone", "'America/Regina'");
236 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Canada/Yukon' }).resolvedOptions().timeZone", "'America/Whitehorse'");
237 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Chile/Continental' }).resolvedOptions().timeZone", "'America/Santiago'");
238 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Chile/EasterIsland' }).resolvedOptions().timeZone", "'Pacific/Easter'");
239 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Cuba' }).resolvedOptions().timeZone", "'America/Havana'");
240 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Egypt' }).resolvedOptions().timeZone", "'Africa/Cairo'");
241 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Eire' }).resolvedOptions().timeZone", "'Europe/Dublin'");
242 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Europe/Belfast' }).resolvedOptions().timeZone", "'Europe/London'");
243 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Europe/Tiraspol' }).resolvedOptions().timeZone", "'Europe/Chisinau'");
244 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'GB' }).resolvedOptions().timeZone", "'Europe/London'");
245 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'GB-Eire' }).resolvedOptions().timeZone", "'Europe/London'");
246 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'GMT+0' }).resolvedOptions().timeZone", "'UTC'");
247 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'GMT-0' }).resolvedOptions().timeZone", "'UTC'");
248 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'GMT0' }).resolvedOptions().timeZone", "'UTC'");
249 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Greenwich' }).resolvedOptions().timeZone", "'UTC'");
250 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Hongkong' }).resolvedOptions().timeZone", "'Asia/Hong_Kong'");
251 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Iceland' }).resolvedOptions().timeZone", "'Atlantic/Reykjavik'");
252 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Iran' }).resolvedOptions().timeZone", "'Asia/Tehran'");
253 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Israel' }).resolvedOptions().timeZone", "'Asia/Jerusalem'");
254 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Jamaica' }).resolvedOptions().timeZone", "'America/Jamaica'");
255 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Japan' }).resolvedOptions().timeZone", "'Asia/Tokyo'");
256 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Kwajalein' }).resolvedOptions().timeZone", "'Pacific/Kwajalein'");
257 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Libya' }).resolvedOptions().timeZone", "'Africa/Tripoli'");
258 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Mexico/BajaNorte' }).resolvedOptions().timeZone", "'America/Tijuana'");
259 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Mexico/BajaSur' }).resolvedOptions().timeZone", "'America/Mazatlan'");
260 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Mexico/General' }).resolvedOptions().timeZone", "'America/Mexico_City'");
261 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'NZ' }).resolvedOptions().timeZone", "'Pacific/Auckland'");
262 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'NZ-CHAT' }).resolvedOptions().timeZone", "'Pacific/Chatham'");
263 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Navajo' }).resolvedOptions().timeZone", "'America/Denver'");
264 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'PRC' }).resolvedOptions().timeZone", "'Asia/Shanghai'");
265 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Poland' }).resolvedOptions().timeZone", "'Europe/Warsaw'");
266 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Portugal' }).resolvedOptions().timeZone", "'Europe/Lisbon'");
267 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'ROC' }).resolvedOptions().timeZone", "'Asia/Taipei'");
268 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'ROK' }).resolvedOptions().timeZone", "'Asia/Seoul'");
269 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Singapore' }).resolvedOptions().timeZone", "'Asia/Singapore'");
270 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Turkey' }).resolvedOptions().timeZone", "'Europe/Istanbul'");
271 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'UCT' }).resolvedOptions().timeZone", "'UTC'");
272 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'US/Alaska' }).resolvedOptions().timeZone", "'America/Anchorage'");
273 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'US/Aleutian' }).resolvedOptions().timeZone", "'America/Adak'");
274 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'US/Arizona' }).resolvedOptions().timeZone", "'America/Phoenix'");
275 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'US/Central' }).resolvedOptions().timeZone", "'America/Chicago'");
276 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'US/Eastern' }).resolvedOptions().timeZone", "'America/New_York'");
277 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'US/Hawaii' }).resolvedOptions().timeZone", "'Pacific/Honolulu'");
278 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'US/Michigan' }).resolvedOptions().timeZone", "'America/Detroit'");
279 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'US/Mountain' }).resolvedOptions().timeZone", "'America/Denver'");
280 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'US/Pacific' }).resolvedOptions().timeZone", "'America/Los_Angeles'");
281 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'US/Samoa' }).resolvedOptions().timeZone", "'Pacific/Pago_Pago'");
282 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'UTC' }).resolvedOptions().timeZone", "'UTC'");
283 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Universal' }).resolvedOptions().timeZone", "'UTC'");
284 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'W-SU' }).resolvedOptions().timeZone", "'Europe/Moscow'");
285 shouldBe("Intl.DateTimeFormat('en', { timeZone: 'Zulu' }).resolvedOptions().timeZone", "'UTC'");
286
287 // Gets default calendar and numberingSystem from locale.
288 shouldBe("Intl.DateTimeFormat('ar-sa').resolvedOptions().locale", "'ar-SA'");
289 shouldBe("Intl.DateTimeFormat('ar-sa').resolvedOptions().calendar", "'islamic-umalqura'");
290 shouldBe("Intl.DateTimeFormat('ar-sa').resolvedOptions().numberingSystem", "'arab'");
291
292 shouldBe("Intl.DateTimeFormat('en', { calendar:'dangi' }).resolvedOptions().calendar", "'gregorian'");
293 shouldBe("Intl.DateTimeFormat('en-u-ca-bogus').resolvedOptions().locale", "'en'");
294 shouldBe("Intl.DateTimeFormat('en-u-ca-bogus').resolvedOptions().calendar", "'gregorian'");
295 shouldBe("Intl.DateTimeFormat('en-u-ca-buddhist').resolvedOptions().locale", "'en-u-ca-buddhist'");
296 shouldBe("Intl.DateTimeFormat('en-u-ca-buddhist').resolvedOptions().calendar", "'buddhist'");
297 shouldBe("Intl.DateTimeFormat('en-u-ca-chinese').resolvedOptions().calendar", "'chinese'");
298 shouldBe("Intl.DateTimeFormat('en-u-ca-coptic').resolvedOptions().calendar", "'coptic'");
299 shouldBe("Intl.DateTimeFormat('en-u-ca-dangi').resolvedOptions().calendar", "'dangi'");
300 shouldBe("Intl.DateTimeFormat('en-u-ca-ethioaa').resolvedOptions().calendar", "'ethiopic-amete-alem'");
301 shouldBe("Intl.DateTimeFormat('en-u-ca-ethiopic').resolvedOptions().calendar", "'ethiopic'");
302 shouldBe("Intl.DateTimeFormat('ar-SA-u-ca-gregory').resolvedOptions().calendar", "'gregorian'");
303 shouldBe("Intl.DateTimeFormat('en-u-ca-hebrew').resolvedOptions().calendar", "'hebrew'");
304 shouldBe("Intl.DateTimeFormat('en-u-ca-indian').resolvedOptions().calendar", "'indian'");
305 shouldBe("Intl.DateTimeFormat('en-u-ca-islamic').resolvedOptions().calendar", "'islamic'");
306 shouldBe("Intl.DateTimeFormat('en-u-ca-islamicc').resolvedOptions().calendar", "'islamic-civil'");
307 shouldBe("Intl.DateTimeFormat('en-u-ca-ISO8601').resolvedOptions().calendar", "'iso8601'");
308 shouldBe("Intl.DateTimeFormat('en-u-ca-japanese').resolvedOptions().calendar", "'japanese'");
309 shouldBe("Intl.DateTimeFormat('en-u-ca-persian').resolvedOptions().calendar", "'persian'");
310 shouldBe("Intl.DateTimeFormat('en-u-ca-roc').resolvedOptions().calendar", "'roc'");
311 // FIXME: https://github.com/tc39/ecma402/issues/59
312 // shouldBe("Intl.DateTimeFormat('en-u-ca-ethiopic-amete-alem').resolvedOptions().calendar", "'ethioaa'");
313 // shouldBe("Intl.DateTimeFormat('en-u-ca-islamic-umalqura').resolvedOptions().calendar", "'islamic-umalqura'");
314 // shouldBe("Intl.DateTimeFormat('en-u-ca-islamic-tbla').resolvedOptions().calendar", "'islamic-tbla'");
315 // shouldBe("Intl.DateTimeFormat('en-u-ca-islamic-civil').resolvedOptions().calendar", "'islamic-civil'");
316 // shouldBe("Intl.DateTimeFormat('en-u-ca-islamic-rgsa').resolvedOptions().calendar", "'islamic-rgsa'");
317
318 shouldBe("Intl.DateTimeFormat('en', { numberingSystem:'gujr' }).resolvedOptions().numberingSystem", "'latn'");
319 shouldBe("Intl.DateTimeFormat('en-u-nu-bogus').resolvedOptions().locale", "'en'");
320 shouldBe("Intl.DateTimeFormat('en-u-nu-bogus').resolvedOptions().numberingSystem", "'latn'");
321 shouldBe("Intl.DateTimeFormat('en-u-nu-latn').resolvedOptions().numberingSystem", "'latn'");
322 shouldBe("Intl.DateTimeFormat('en-u-nu-arab').resolvedOptions().locale", "'en-u-nu-arab'");
323
324 let numberingSystems = [
325   "arab", "arabext", "armn", "armnlow", "bali", "beng", "cham", "deva", "ethi",
326   "fullwide", "geor", "grek", "greklow", "gujr", "guru", "hanidays", "hanidec",
327   "hans", "hansfin", "hant", "hantfin", "hebr", "java", "jpan", "jpanfin",
328   "kali", "khmr", "knda", "lana", "lanatham", "laoo", "latn", "lepc", "limb",
329   "mlym", "mong", "mtei", "mymr", "mymrshan", "nkoo", "olck", "orya", "roman",
330   "romanlow", "saur", "sund", "talu", "taml", "tamldec", "telu", "thai", "tibt",
331   "vaii"
332 ]
333 for (let numberingSystem of numberingSystems) {
334   shouldBe(`Intl.DateTimeFormat('en-u-nu-${numberingSystem}').resolvedOptions().numberingSystem`, `'${numberingSystem}'`);
335 }
336
337 shouldThrow("Intl.DateTimeFormat('en', { weekday: { toString() { throw 'weekday' } } })", "'weekday'");
338 shouldThrow("Intl.DateTimeFormat('en', { weekday:'invalid' })", '\'RangeError: weekday must be "narrow", "short", or "long"\'');
339 shouldBe("Intl.DateTimeFormat('en', { minute:'2-digit', hour:'numeric' }).resolvedOptions().weekday", "undefined");
340 shouldBe("Intl.DateTimeFormat('en', { weekday:'narrow', month:'numeric', day:'numeric' }).resolvedOptions().weekday", "'narrow'");
341 shouldBe("Intl.DateTimeFormat('en', { weekday:'short', month:'numeric', day:'numeric' }).resolvedOptions().weekday", "'short'");
342 shouldBe("Intl.DateTimeFormat('en', { weekday:'long', month:'numeric', day:'numeric' }).resolvedOptions().weekday", "'long'");
343
344 shouldThrow("Intl.DateTimeFormat('en', { era: { toString() { throw 'era' } } })", "'era'");
345 shouldThrow("Intl.DateTimeFormat('en', { era:'never' })", '\'RangeError: era must be "narrow", "short", or "long"\'');
346 shouldBe("Intl.DateTimeFormat('en', { minute:'2-digit', hour:'numeric' }).resolvedOptions().day", "undefined");
347 shouldBe("Intl.DateTimeFormat('en', { era:'narrow', year:'numeric' }).resolvedOptions().era", "'narrow'");
348 shouldBe("Intl.DateTimeFormat('en', { era:'short', year:'numeric' }).resolvedOptions().era", "'short'");
349 shouldBe("Intl.DateTimeFormat('en', { era:'long', year:'numeric' }).resolvedOptions().era", "'long'");
350
351 shouldThrow("Intl.DateTimeFormat('en', { year: { toString() { throw 'year' } } })", "'year'");
352 shouldThrow("Intl.DateTimeFormat('en', { year:'nope' })", '\'RangeError: year must be "2-digit" or "numeric"\'');
353 shouldBe("Intl.DateTimeFormat('en', { minute:'2-digit', hour:'numeric' }).resolvedOptions().year", "undefined");
354 shouldBe("Intl.DateTimeFormat('en', { era:'narrow', year:'2-digit' }).resolvedOptions().year", "'2-digit'");
355 shouldBe("Intl.DateTimeFormat('en', { era:'narrow', year:'numeric' }).resolvedOptions().year", "'numeric'");
356
357 shouldThrow("Intl.DateTimeFormat('en', { month: { toString() { throw 'month' } } })", "'month'");
358 shouldThrow("Intl.DateTimeFormat('en', { month:2 })", '\'RangeError: month must be "2-digit", "numeric", "narrow", "short", or "long"\'');
359 shouldBe("Intl.DateTimeFormat('en', { minute:'2-digit', hour:'numeric' }).resolvedOptions().month", "undefined");
360 shouldBe("Intl.DateTimeFormat('en', { month:'2-digit', year:'numeric' }).resolvedOptions().month", "'2-digit'");
361 shouldBe("Intl.DateTimeFormat('en', { month:'numeric', year:'numeric' }).resolvedOptions().month", "'numeric'");
362 shouldBe("Intl.DateTimeFormat('en', { month:'narrow', year:'numeric' }).resolvedOptions().month", "'narrow'");
363 shouldBe("Intl.DateTimeFormat('en', { month:'short', year:'numeric' }).resolvedOptions().month", "'short'");
364 shouldBe("Intl.DateTimeFormat('en', { month:'long', year:'numeric' }).resolvedOptions().month", "'long'");
365
366 shouldThrow("Intl.DateTimeFormat('en', { day: { toString() { throw 'day' } } })", "'day'");
367 shouldThrow("Intl.DateTimeFormat('en', { day:'' })", '\'RangeError: day must be "2-digit" or "numeric"\'');
368 shouldBe("Intl.DateTimeFormat('en', { minute:'2-digit', hour:'numeric' }).resolvedOptions().day", "undefined");
369 shouldBe("Intl.DateTimeFormat('en', { month:'long', day:'2-digit' }).resolvedOptions().day", "'2-digit'");
370 shouldBe("Intl.DateTimeFormat('en', { month:'long', day:'numeric' }).resolvedOptions().day", "'numeric'");
371
372 shouldThrow("Intl.DateTimeFormat('en', { hour: { toString() { throw 'hour' } } })", "'hour'");
373 shouldThrow("Intl.DateTimeFormat('en', { hour:[] })", '\'RangeError: hour must be "2-digit" or "numeric"\'');
374 shouldBe("Intl.DateTimeFormat('en').resolvedOptions().hour", "undefined");
375 shouldBe("Intl.DateTimeFormat('en', { minute:'2-digit', hour:'2-digit' }).resolvedOptions().hour", "'numeric'");
376 shouldBe("Intl.DateTimeFormat('en', { minute:'2-digit', hour:'numeric' }).resolvedOptions().hour", "'numeric'");
377
378 shouldBe("Intl.DateTimeFormat('en').resolvedOptions().hour12", "undefined");
379 shouldBe("Intl.DateTimeFormat('en', { minute:'2-digit', hour:'numeric' }).resolvedOptions().hour12", "true");
380 shouldBe("Intl.DateTimeFormat('pt-BR', { minute:'2-digit', hour:'numeric' }).resolvedOptions().hour12", "false");
381
382 shouldThrow("Intl.DateTimeFormat('en', { minute: { toString() { throw 'minute' } } })", "'minute'");
383 shouldThrow("Intl.DateTimeFormat('en', { minute:null })", '\'RangeError: minute must be "2-digit" or "numeric"\'');
384 shouldBe("Intl.DateTimeFormat('en').resolvedOptions().minute", "undefined");
385 shouldBe("Intl.DateTimeFormat('en', { minute:'2-digit', hour:'numeric' }).resolvedOptions().minute", "'2-digit'");
386 shouldBe("Intl.DateTimeFormat('en', { minute:'numeric', hour:'numeric' }).resolvedOptions().minute", "'2-digit'");
387
388 shouldThrow("Intl.DateTimeFormat('en', { second: { toString() { throw 'second' } } })", "'second'");
389 shouldThrow("Intl.DateTimeFormat('en', { second:'badvalue' })", '\'RangeError: second must be "2-digit" or "numeric"\'');
390 shouldBe("Intl.DateTimeFormat('en').resolvedOptions().second", "undefined");
391 shouldBe("Intl.DateTimeFormat('en', { minute:'numeric', hour:'numeric', second:'2-digit' }).resolvedOptions().second", "'2-digit'");
392 shouldBe("Intl.DateTimeFormat('en', { minute:'numeric', hour:'numeric', second:'numeric' }).resolvedOptions().second", "'2-digit'");
393
394 shouldThrow("Intl.DateTimeFormat('en', { timeZoneName: { toString() { throw 'timeZoneName' } } })", "'timeZoneName'");
395 shouldThrow("Intl.DateTimeFormat('en', { timeZoneName:'name' })", '\'RangeError: timeZoneName must be "short" or "long"\'');
396 shouldBe("Intl.DateTimeFormat('en').resolvedOptions().timeZoneName", "undefined");
397 shouldBe("Intl.DateTimeFormat('en', { minute:'2-digit', hour:'numeric', timeZoneName:'short' }).resolvedOptions().timeZoneName", "'short'");
398 shouldBe("Intl.DateTimeFormat('pt-BR', { minute:'2-digit', hour:'numeric', timeZoneName:'long' }).resolvedOptions().timeZoneName", "'long'");
399
400 let localesSample = [
401   "ar", "ar-SA", "be", "ca", "cs", "da", "de", "de-CH", "en", "en-AU", "en-GB",
402   "en-PH", "en-US", "el", "es", "es-MX", "es-PR", "fr", "fr-CA", "ga", "hi-IN",
403   "is", "it", "iw", "ja", "ko-KR", "lt", "lv", "mk", "ms", "mt", "nb", "nl",
404   "no", "pl", "pt", "pt-BR", "ro", "ru", "sk", "sl", "sr", "sv", "th", "tr",
405   "uk", "vi", "zh", "zh-CN", "zh-Hant-HK", "zh-TW"
406 ];
407 for (let locale of localesSample) {
408   // The following subsets must be available for each locale:
409   // weekday, year, month, day, hour, minute, second
410   shouldBeTrue(`
411     var options = { weekday: "short", year: "numeric", month: "short", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric" };
412     var resolved = Intl.DateTimeFormat("${locale}", options).resolvedOptions();
413     Object.keys(options).every(option => resolved[option] != null)`);
414   // weekday, year, month, day
415   shouldBeTrue(`
416     var options = { weekday: "short", year: "numeric", month: "short", day: "numeric" };
417     var resolved = Intl.DateTimeFormat("${locale}", options).resolvedOptions();
418     Object.keys(options).every(option => resolved[option] != null)`);
419   // year, month, day
420   shouldBeTrue(`
421     var options = { year: "numeric", month: "long", day: "numeric" };
422     var resolved = Intl.DateTimeFormat("${locale}", options).resolvedOptions();
423     Object.keys(options).every(option => resolved[option] != null)`);
424   // year, month
425   shouldBeTrue(`
426     var options = { year: "numeric", month: "long" };
427     var resolved = Intl.DateTimeFormat("${locale}", options).resolvedOptions();
428     Object.keys(options).every(option => resolved[option] != null)`);
429   // month, day
430   shouldBeTrue(`
431     var options = { month: "long", day: "numeric" };
432     var resolved = Intl.DateTimeFormat("${locale}", options).resolvedOptions();
433     Object.keys(options).every(option => resolved[option] != null)`);
434   // hour, minute, second
435   shouldBeTrue(`
436     var options = { hour: "numeric", minute: "numeric", second: "numeric" };
437     var resolved = Intl.DateTimeFormat("${locale}", options).resolvedOptions();
438     Object.keys(options).every(option => resolved[option] != null)`);
439   // hour, minute
440   shouldBeTrue(`
441     var options = { hour: "numeric", minute: "numeric" };
442     var resolved = Intl.DateTimeFormat("${locale}", options).resolvedOptions();
443     Object.keys(options).every(option => resolved[option] != null)`);
444 }