Skip to content

Commit ae03d21

Browse files
committed
Tests for new API Temporal.TimeZone.p.equals
1 parent 85e2b49 commit ae03d21

19 files changed

+1219
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.prototype.equals
6+
description: Tests that objects can be compared for equality
7+
features: [Temporal]
8+
---*/
9+
10+
class CustomTimeZone extends Temporal.TimeZone {
11+
constructor(id) {
12+
super("UTC");
13+
this._id = id;
14+
}
15+
get id() {
16+
return this._id;
17+
}
18+
}
19+
20+
const objectsEqualUTC = [
21+
new Temporal.TimeZone("UTC"),
22+
new CustomTimeZone("UTC"),
23+
{ id: "UTC", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
24+
new Temporal.ZonedDateTime(0n, "UTC")
25+
];
26+
27+
const tzUTC = new Temporal.TimeZone("UTC");
28+
29+
for (const object of objectsEqualUTC) {
30+
const result = tzUTC.equals(object);
31+
assert.sameValue(result, true);
32+
}
33+
34+
const objectsEqual0000 = [
35+
new Temporal.TimeZone("+00:00"),
36+
new Temporal.TimeZone("+0000"),
37+
new Temporal.TimeZone("+00"),
38+
new CustomTimeZone("+00:00"),
39+
new CustomTimeZone("+0000"),
40+
new CustomTimeZone("+00"),
41+
{ id: "+00:00", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
42+
{ id: "+0000", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
43+
{ id: "+00", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
44+
new Temporal.ZonedDateTime(0n, "+00:00"),
45+
new Temporal.ZonedDateTime(0n, "+0000"),
46+
new Temporal.ZonedDateTime(0n, "+00")
47+
];
48+
49+
const tz0000 = new Temporal.TimeZone("+00:00");
50+
51+
for (const object of objectsEqual0000) {
52+
const result = tz0000.equals(object);
53+
assert.sameValue(result, true);
54+
}
55+
56+
const objectsNotEqual = [
57+
new Temporal.TimeZone("+00:00"),
58+
new CustomTimeZone("+00:00"),
59+
{ id: "+00:00", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
60+
{ id: "Etc/Custom", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
61+
new Temporal.ZonedDateTime(0n, "+00:00")
62+
];
63+
64+
for (const object of objectsNotEqual) {
65+
const result = tzUTC.equals(object);
66+
assert.sameValue(result, false);
67+
}
68+
69+
// Custom object IDs are compared case-sensitively
70+
const classInstanceCustomId = new CustomTimeZone("Moon/Cheese");
71+
const classInstanceSameCaseCustomId = new CustomTimeZone("Moon/Cheese");
72+
const classInstanceDifferentCaseCustomId = new CustomTimeZone("MoOn/CHEESe");
73+
74+
const plainObjectSameCaseCustomId = { id: "Moon/Cheese", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null };
75+
const plainObjectDifferentCaseCustomId = {
76+
id: "MoOn/CHEESe",
77+
getPossibleInstantsFor: null,
78+
getOffsetNanosecondsFor: null
79+
};
80+
81+
assert.sameValue(classInstanceCustomId.equals(classInstanceSameCaseCustomId), true);
82+
assert.sameValue(classInstanceCustomId.equals(classInstanceDifferentCaseCustomId), false);
83+
assert.sameValue(classInstanceCustomId.equals(plainObjectSameCaseCustomId), true);
84+
assert.sameValue(classInstanceCustomId.equals(plainObjectDifferentCaseCustomId), false);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.from
6+
description: Exceptions thrown if a value is passed that converts to an invalid string
7+
features: [Temporal]
8+
---*/
9+
10+
const primitives = [
11+
undefined,
12+
null,
13+
true,
14+
"string",
15+
"local",
16+
"Z",
17+
"-00:00[UTC]",
18+
"+00:01.1",
19+
"-01.1",
20+
"1994-11-05T08:15:30+25:00",
21+
"1994-11-05T13:15:30-25:00",
22+
7,
23+
4.2,
24+
12n
25+
];
26+
27+
const tzUTC = new Temporal.TimeZone("UTC");
28+
for (const primitive of primitives) {
29+
assert.throws(typeof primitive === "string" ? RangeError : TypeError, () => tzUTC.equals(primitive));
30+
}
31+
32+
const symbol = Symbol();
33+
assert.throws(TypeError, () => tzUTC.equals(symbol));
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.from
6+
description: Built-in time zones are compared correctly out of valid strings
7+
features: [Temporal]
8+
---*/
9+
10+
const validsEqual = [
11+
["+0330", "+03:30"],
12+
["-0650", "-06:50"],
13+
["-08", "-08:00"],
14+
["\u221201:00", "-01:00"],
15+
["\u22120650", "-06:50"],
16+
["\u221208", "-08:00"],
17+
["1994-11-05T08:15:30-05:00", "-05:00"],
18+
["1994-11-05T08:15:30\u221205:00", "-05:00"],
19+
["1994-11-05T13:15:30Z", "UTC"]
20+
];
21+
22+
for (const [valid, canonical] of validsEqual) {
23+
const tzValid = Temporal.TimeZone.from(valid);
24+
const tzCanonical = Temporal.TimeZone.from(canonical);
25+
assert.sameValue(tzValid.equals(canonical), true);
26+
assert.sameValue(tzCanonical.equals(valid), true);
27+
}
28+
29+
const validsNotEqual = [
30+
["+0330", "+03:31"],
31+
["-0650", "-06:51"],
32+
["-08", "-08:01"],
33+
["\u221201:00", "-01:01"],
34+
["\u22120650", "-06:51"],
35+
["\u221208", "-08:01"],
36+
["1994-11-05T08:15:30-05:00", "-05:01"],
37+
["1994-11-05T08:15:30\u221205:00", "-05:01"]
38+
];
39+
40+
for (const [valid, canonical] of validsNotEqual) {
41+
const tzValid = Temporal.TimeZone.from(valid);
42+
const tzCanonical = Temporal.TimeZone.from(canonical);
43+
assert.sameValue(tzValid.equals(canonical), false);
44+
assert.sameValue(tzCanonical.equals(valid), false);
45+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.prototype.equals
6+
description: Throw a TypeError if the receiver is invalid
7+
features: [Symbol, Temporal]
8+
---*/
9+
10+
const equals = Temporal.TimeZone.prototype.equals;
11+
12+
assert.sameValue(typeof equals, "function");
13+
14+
const args = ["UTC"];
15+
16+
assert.throws(TypeError, () => equals.apply(undefined, args), "undefined");
17+
assert.throws(TypeError, () => equals.apply(null, args), "null");
18+
assert.throws(TypeError, () => equals.apply(true, args), "true");
19+
assert.throws(TypeError, () => equals.apply("", args), "empty string");
20+
assert.throws(TypeError, () => equals.apply(Symbol(), args), "symbol");
21+
assert.throws(TypeError, () => equals.apply(1, args), "1");
22+
assert.throws(TypeError, () => equals.apply({}, args), "plain object");
23+
assert.throws(TypeError, () => equals.apply(Temporal.TimeZone, args), "Temporal.TimeZone");
24+
assert.throws(TypeError, () => equals.apply(Temporal.TimeZone.prototype, args), "Temporal.TimeZone.prototype");
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.prototype.equals
6+
description: >
7+
Tests that Temporal.TimeZone.prototype.equals
8+
meets the requirements for built-in objects defined by the
9+
introduction of chapter 17 of the ECMAScript Language Specification.
10+
info: |
11+
Built-in functions that are not constructors do not have a "prototype" property unless
12+
otherwise specified in the description of a particular function.
13+
14+
Unless specified otherwise, a built-in object that is callable as a function is a built-in
15+
function object with the characteristics described in 10.3. Unless specified otherwise, the
16+
[[Extensible]] internal slot of a built-in object initially has the value true.
17+
18+
Unless otherwise specified every built-in function and every built-in constructor has the
19+
Function prototype object [...] as the value of its [[Prototype]] internal slot.
20+
features: [Temporal]
21+
---*/
22+
23+
assert.sameValue(Object.isExtensible(Temporal.TimeZone.prototype.equals),
24+
true, "Built-in objects must be extensible.");
25+
26+
assert.sameValue(Object.prototype.toString.call(Temporal.TimeZone.prototype.equals),
27+
"[object Function]", "Object.prototype.toString");
28+
29+
assert.sameValue(Object.getPrototypeOf(Temporal.TimeZone.prototype.equals),
30+
Function.prototype, "prototype");
31+
32+
assert.sameValue(Temporal.TimeZone.prototype.equals.hasOwnProperty("prototype"),
33+
false, "prototype property");
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.prototype.equals
6+
description: Temporal.TimeZone.prototype.equals.length is 1
7+
info: |
8+
Every built-in function object, including constructors, has a "length" property whose value is
9+
an integer. Unless otherwise specified, this value is equal to the largest number of named
10+
arguments shown in the subclause headings for the function description. Optional parameters
11+
(which are indicated with brackets: [ ]) or rest parameters (which are shown using the form
12+
«...name») are not included in the default argument count.
13+
14+
Unless otherwise specified, the "length" property of a built-in function object has the
15+
attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
16+
includes: [propertyHelper.js]
17+
features: [Temporal]
18+
---*/
19+
20+
verifyProperty(Temporal.TimeZone.prototype.equals, "length", {
21+
value: 1,
22+
writable: false,
23+
enumerable: false,
24+
configurable: true,
25+
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.prototype.equals
6+
description: Temporal.TimeZone.prototype.equals.name is "equals".
7+
info: |
8+
Every built-in function object, including constructors, that is not identified as an anonymous
9+
function has a "name" property whose value is a String. Unless otherwise specified, this value
10+
is the name that is given to the function in this specification.
11+
12+
Unless otherwise specified, the "name" property of a built-in function object, if it exists,
13+
has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
14+
includes: [propertyHelper.js]
15+
features: [Temporal]
16+
---*/
17+
18+
verifyProperty(Temporal.TimeZone.prototype.equals, "name", {
19+
value: "equals",
20+
writable: false,
21+
enumerable: false,
22+
configurable: true,
23+
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.prototype.equals
6+
description: >
7+
Temporal.TimeZone.prototype.equals does not implement [[Construct]], is not new-able
8+
info: |
9+
Built-in function objects that are not identified as constructors do not implement the
10+
[[Construct]] internal method unless otherwise specified in the description of a particular
11+
function.
12+
includes: [isConstructor.js]
13+
features: [Reflect.construct, Temporal]
14+
---*/
15+
16+
assert.throws(TypeError, () => {
17+
new Temporal.TimeZone.prototype.equals();
18+
}, "Calling as constructor");
19+
20+
assert.sameValue(isConstructor(Temporal.TimeZone.prototype.equals), false,
21+
"isConstructor(Temporal.TimeZone.prototype.equals)");
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.prototype.equals
6+
description: The "equals" property of Temporal.TimeZone.prototype
7+
includes: [propertyHelper.js]
8+
features: [Temporal]
9+
---*/
10+
11+
assert.sameValue(
12+
typeof Temporal.TimeZone.prototype.equals,
13+
"function",
14+
"`typeof TimeZone.prototype.equals` is `function`"
15+
);
16+
17+
verifyProperty(Temporal.TimeZone.prototype, "equals", {
18+
writable: true,
19+
enumerable: false,
20+
configurable: true,
21+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.equals
6+
description: Time zone names are case insensitive
7+
features: [Temporal]
8+
---*/
9+
10+
const timeZone = 'UtC';
11+
const result = Temporal.TimeZone.from(timeZone);
12+
assert.sameValue(result.equals(timeZone), true);
13+
assert.sameValue(result.equals("+00:00"), false);
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.equals
6+
description: Conversion of ISO date-time strings to the argument of Temporal.TimeZone.prototype.equals
7+
features: [Temporal]
8+
---*/
9+
10+
let tzUTC = Temporal.TimeZone.from("UTC");
11+
let arg = "2021-08-19T17:30";
12+
assert.throws(RangeError, () => tzUTC.equals(arg), "bare date-time string is not a time zone");
13+
14+
arg = "2021-08-19T17:30-07:00:01";
15+
assert.throws(RangeError, () => tzUTC.equals(arg), "ISO string sub-minute offset is not OK as time zone");
16+
17+
arg = "2021-08-19T17:30Z";
18+
tzUTC = Temporal.TimeZone.from(arg);
19+
assert.sameValue(tzUTC.equals(arg), true, "date-time + Z is UTC time zone");
20+
21+
arg = "2021-08-19T17:30-07:00";
22+
tzUTC = Temporal.TimeZone.from(arg);
23+
assert.sameValue(tzUTC.equals(arg), true, "date-time + offset is the offset time zone");
24+
25+
arg = "2021-08-19T17:30[UTC]";
26+
tzUTC = Temporal.TimeZone.from(arg);
27+
assert.sameValue(tzUTC.equals(arg), true, "date-time + IANA annotation is the IANA time zone");
28+
29+
arg = "2021-08-19T17:30Z[UTC]";
30+
tzUTC = Temporal.TimeZone.from(arg);
31+
assert.sameValue(tzUTC.equals(arg), true, "date-time + Z + IANA annotation is the IANA time zone");
32+
33+
arg = "2021-08-19T17:30-07:00[UTC]";
34+
tzUTC = Temporal.TimeZone.from(arg);
35+
assert.sameValue(tzUTC.equals(arg), true, "date-time + offset + IANA annotation is the IANA time zone");
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (C) 2023 Justin Grant. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-temporal.timezone.from
6+
description: Time zone strings with UTC offset fractional part are not confused with time fractional part
7+
features: [Temporal]
8+
---*/
9+
10+
const timeZone = "2021-08-19T17:30:45.123456789-12:12[+01:46]";
11+
12+
const result = Temporal.TimeZone.from(timeZone);
13+
assert.sameValue(result.equals("+01:46"), true, "Time zone string determined from bracket name");

0 commit comments

Comments
 (0)