Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests for proposal-canonical-tz Stage 3 (will be merged into Temporal) #3837

Merged
merged 5 commits into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions test/built-ins/Temporal/TimeZone/prototype/equals/argument-object.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright (C) 2023 Justin Grant. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.timezone.prototype.equals
description: Tests that objects can be compared for equality
features: [Temporal]
---*/

class CustomTimeZone extends Temporal.TimeZone {
constructor(id) {
super("UTC");
this._id = id;
}
get id() {
return this._id;
}
}

const objectsEqualUTC = [
new Temporal.TimeZone("UTC"),
new CustomTimeZone("UTC"),
{ id: "UTC", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
new Temporal.ZonedDateTime(0n, "UTC")
];

const tzUTC = new Temporal.TimeZone("UTC");

for (const object of objectsEqualUTC) {
const result = tzUTC.equals(object);
assert.sameValue(result, true, `Receiver ${tzUTC.id} should equal argument ${object.id}`);
}

const objectsEqual0000 = [
new Temporal.TimeZone("+00:00"),
new Temporal.TimeZone("+0000"),
new Temporal.TimeZone("+00"),
new CustomTimeZone("+00:00"),
new CustomTimeZone("+0000"),
new CustomTimeZone("+00"),
{ id: "+00:00", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
{ id: "+0000", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
{ id: "+00", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
new Temporal.ZonedDateTime(0n, "+00:00"),
new Temporal.ZonedDateTime(0n, "+0000"),
new Temporal.ZonedDateTime(0n, "+00"),
"+00:00",
"+0000",
"+00"
];

const tz0000ToTest = [
new Temporal.TimeZone("+00:00"),
new Temporal.TimeZone("+0000"),
new Temporal.TimeZone("+00"),
new CustomTimeZone("+00:00"),
new CustomTimeZone("+0000"),
new CustomTimeZone("+00")
];

for (const arg of objectsEqual0000) {
for (const receiver of tz0000ToTest) {
const result = receiver.equals(arg);
assert.sameValue(result, true, `Receiver ${receiver.id} should equal argument ${arg.id ?? arg}`);
}
}

const objectsNotEqual = [
new Temporal.TimeZone("+00:00"),
new CustomTimeZone("+00:00"),
new CustomTimeZone("Etc/Custom"),
{ id: "+00:00", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
{ id: "Etc/Custom", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null },
new Temporal.ZonedDateTime(0n, "+00:00"),
"UTC"
];

const customObjectsToTest = [tzUTC, new CustomTimeZone("YouTeeSee"), new CustomTimeZone("+01:00")];

for (const arg of objectsNotEqual) {
for (const receiver of customObjectsToTest) {
if (arg === "UTC" && receiver === tzUTC) continue;
const result = receiver.equals(arg);
assert.sameValue(result, false, `Receiver ${receiver.id} should not equal argument ${arg.id ?? arg}`);
}
}

// Custom object IDs are compared case-sensitively
const classInstanceCustomId = new CustomTimeZone("Moon/Cheese");
const classInstanceSameCaseCustomId = new CustomTimeZone("Moon/Cheese");
const classInstanceDifferentCaseCustomId = new CustomTimeZone("MoOn/CHEESe");

const plainObjectSameCaseCustomId = { id: "Moon/Cheese", getPossibleInstantsFor: null, getOffsetNanosecondsFor: null };
const plainObjectDifferentCaseCustomId = {
id: "MoOn/CHEESe",
getPossibleInstantsFor: null,
getOffsetNanosecondsFor: null
};

assert.sameValue(classInstanceCustomId.equals(classInstanceSameCaseCustomId), true);
assert.sameValue(classInstanceCustomId.equals(classInstanceDifferentCaseCustomId), false);
assert.sameValue(classInstanceCustomId.equals(plainObjectSameCaseCustomId), true);
assert.sameValue(classInstanceCustomId.equals(plainObjectDifferentCaseCustomId), false);
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (C) 2023 Justin Grant. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.timezone.from
description: Exceptions thrown if a value is passed that converts to an invalid string
features: [Temporal]
---*/

const primitives = [
undefined,
null,
true,
"string",
"local",
"Z",
"-00:00[UTC]",
"+00:01.1",
"-01.1",
"1994-11-05T08:15:30+25:00",
"1994-11-05T13:15:30-25:00",
7,
4.2,
12n
];

const tzUTC = new Temporal.TimeZone("UTC");
for (const primitive of primitives) {
assert.throws(typeof primitive === "string" ? RangeError : TypeError, () => tzUTC.equals(primitive));
}

const symbol = Symbol();
assert.throws(TypeError, () => tzUTC.equals(symbol));
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (C) 2023 Justin Grant. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.timezone.from
description: Built-in time zones are compared correctly out of valid strings
features: [Temporal]
---*/

const validsEqual = [
["+0330", "+03:30"],
["-0650", "-06:50"],
["-08", "-08:00"],
["\u221201:00", "-01:00"],
["\u22120650", "-06:50"],
["\u221208", "-08:00"],
["1994-11-05T08:15:30-05:00", "-05:00"],
["1994-11-05T08:15:30\u221205:00", "-05:00"],
["1994-11-05T13:15:30Z", "UTC"]
];

for (const [valid, canonical] of validsEqual) {
const tzValid = Temporal.TimeZone.from(valid);
const tzCanonical = Temporal.TimeZone.from(canonical);
assert.sameValue(tzValid.equals(canonical), true);
assert.sameValue(tzCanonical.equals(valid), true);
}

const validsNotEqual = [
["+0330", "+03:31"],
["-0650", "-06:51"],
["-08", "-08:01"],
["\u221201:00", "-01:01"],
["\u22120650", "-06:51"],
["\u221208", "-08:01"],
["1994-11-05T08:15:30-05:00", "-05:01"],
["1994-11-05T08:15:30\u221205:00", "-05:01"]
];

for (const [valid, canonical] of validsNotEqual) {
const tzValid = Temporal.TimeZone.from(valid);
const tzCanonical = Temporal.TimeZone.from(canonical);
assert.sameValue(tzValid.equals(canonical), false);
assert.sameValue(tzCanonical.equals(valid), false);
}
24 changes: 24 additions & 0 deletions test/built-ins/Temporal/TimeZone/prototype/equals/branding.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (C) 2023 Justin Grant. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.timezone.prototype.equals
description: Throw a TypeError if the receiver is invalid
features: [Symbol, Temporal]
---*/

const equals = Temporal.TimeZone.prototype.equals;

assert.sameValue(typeof equals, "function");

const args = ["UTC"];

assert.throws(TypeError, () => equals.apply(undefined, args), "undefined");
assert.throws(TypeError, () => equals.apply(null, args), "null");
assert.throws(TypeError, () => equals.apply(true, args), "true");
assert.throws(TypeError, () => equals.apply("", args), "empty string");
assert.throws(TypeError, () => equals.apply(Symbol(), args), "symbol");
assert.throws(TypeError, () => equals.apply(1, args), "1");
assert.throws(TypeError, () => equals.apply({}, args), "plain object");
assert.throws(TypeError, () => equals.apply(Temporal.TimeZone, args), "Temporal.TimeZone");
assert.throws(TypeError, () => equals.apply(Temporal.TimeZone.prototype, args), "Temporal.TimeZone.prototype");
33 changes: 33 additions & 0 deletions test/built-ins/Temporal/TimeZone/prototype/equals/builtin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (C) 2023 Justin Grant. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.timezone.prototype.equals
description: >
Tests that Temporal.TimeZone.prototype.equals
meets the requirements for built-in objects defined by the
introduction of chapter 17 of the ECMAScript Language Specification.
info: |
Built-in functions that are not constructors do not have a "prototype" property unless
otherwise specified in the description of a particular function.

Unless specified otherwise, a built-in object that is callable as a function is a built-in
function object with the characteristics described in 10.3. Unless specified otherwise, the
[[Extensible]] internal slot of a built-in object initially has the value true.

Unless otherwise specified every built-in function and every built-in constructor has the
Function prototype object [...] as the value of its [[Prototype]] internal slot.
features: [Temporal]
---*/

assert.sameValue(Object.isExtensible(Temporal.TimeZone.prototype.equals),
true, "Built-in objects must be extensible.");

assert.sameValue(Object.prototype.toString.call(Temporal.TimeZone.prototype.equals),
"[object Function]", "Object.prototype.toString");

assert.sameValue(Object.getPrototypeOf(Temporal.TimeZone.prototype.equals),
Function.prototype, "prototype");

assert.sameValue(Temporal.TimeZone.prototype.equals.hasOwnProperty("prototype"),
false, "prototype property");
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (C) 2023 Justin Grant. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.timezone.prototype.equals
description: TypeError thrown if time zone reports an id that is not a String
features: [Temporal]
---*/

class CustomTimeZone extends Temporal.TimeZone {
constructor(id) {
super("UTC");
this._id = id;
}
get id() {
return this._id;
}
}

[
undefined,
null,
true,
-1000,
Symbol(),
3600_000_000_000n,
{},
{
valueOf() {
return 3600_000_000_000;
}
}
].forEach((wrongId) => {
const timeZoneWrong = new CustomTimeZone(wrongId);
const timeZoneOK = new Temporal.TimeZone('UTC');
assert.throws(TypeError, () => timeZoneWrong.equals(timeZoneOK));
assert.throws(TypeError, () => timeZoneOK.equals(timeZoneWrong));
});
25 changes: 25 additions & 0 deletions test/built-ins/Temporal/TimeZone/prototype/equals/length.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2023 Justin Grant. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.timezone.prototype.equals
description: Temporal.TimeZone.prototype.equals.length is 1
info: |
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]
features: [Temporal]
---*/

verifyProperty(Temporal.TimeZone.prototype.equals, "length", {
value: 1,
writable: false,
enumerable: false,
configurable: true,
});
23 changes: 23 additions & 0 deletions test/built-ins/Temporal/TimeZone/prototype/equals/name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (C) 2023 Justin Grant. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.timezone.prototype.equals
description: Temporal.TimeZone.prototype.equals.name is "equals".
info: |
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, this value
is the name that is given to the function in this specification.

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]
features: [Temporal]
---*/

verifyProperty(Temporal.TimeZone.prototype.equals, "name", {
value: "equals",
writable: false,
enumerable: false,
configurable: true,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (C) 2023 Justin Grant. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.timezone.prototype.equals
description: >
Temporal.TimeZone.prototype.equals does not implement [[Construct]], is not new-able
info: |
Built-in function objects that are not identified as constructors do not implement the
[[Construct]] internal method unless otherwise specified in the description of a particular
function.
includes: [isConstructor.js]
features: [Reflect.construct, Temporal]
---*/

assert.throws(TypeError, () => {
new Temporal.TimeZone.prototype.equals();
}, "Calling as constructor");

assert.sameValue(isConstructor(Temporal.TimeZone.prototype.equals), false,
"isConstructor(Temporal.TimeZone.prototype.equals)");
21 changes: 21 additions & 0 deletions test/built-ins/Temporal/TimeZone/prototype/equals/prop-desc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (C) 2023 Justin Grant. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.timezone.prototype.equals
description: The "equals" property of Temporal.TimeZone.prototype
includes: [propertyHelper.js]
features: [Temporal]
---*/

assert.sameValue(
typeof Temporal.TimeZone.prototype.equals,
"function",
"`typeof TimeZone.prototype.equals` is `function`"
);

verifyProperty(Temporal.TimeZone.prototype, "equals", {
writable: true,
enumerable: false,
configurable: true,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (C) 2023 Justin Grant. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.timezone.equals
description: Time zone names are case insensitive
features: [Temporal]
---*/

const timeZone = 'UtC';
const result = Temporal.TimeZone.from(timeZone);
assert.sameValue(result.equals(timeZone), true);
assert.sameValue(result.equals("+00:00"), false);
Loading