summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS/Tests
diff options
context:
space:
mode:
authorLuke Wilde <lukew@serenityos.org>2021-09-08 18:59:09 +0100
committerLinus Groh <mail@linusgroh.de>2021-09-08 19:57:29 +0100
commitd943b8f1005e4446ffe9bfd84dbd1014025f35d2 (patch)
treea3e262d580f5afd1a4ede7a0527eaa5c7e4d1012 /Userland/Libraries/LibJS/Tests
parentb8d683c5fb57fac120405d31792a363b6f4e0d85 (diff)
downloadserenity-d943b8f1005e4446ffe9bfd84dbd1014025f35d2.zip
LibJS: Implement Temporal.PlainTime.prototype.with
Ticks off one box in #8982 and fixes one test262 case.
Diffstat (limited to 'Userland/Libraries/LibJS/Tests')
-rw-r--r--Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainTime/PlainTime.prototype.with.js210
1 files changed, 210 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainTime/PlainTime.prototype.with.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainTime/PlainTime.prototype.with.js
new file mode 100644
index 0000000000..a0ffa7fb99
--- /dev/null
+++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainTime/PlainTime.prototype.with.js
@@ -0,0 +1,210 @@
+const PLAIN_TIME_PROPERTIES = [
+ "hour",
+ "minute",
+ "second",
+ "millisecond",
+ "microsecond",
+ "nanosecond",
+];
+
+const REJECTED_CALENDAR_TYPES_THREE_ARGUMENTS = [
+ Temporal.PlainDate,
+ Temporal.PlainDateTime,
+ Temporal.PlainTime,
+];
+
+const REJECTED_CALENDAR_TYPES_TWO_ARGUMENTS = [Temporal.PlainMonthDay, Temporal.PlainYearMonth];
+
+describe("correct behaviour", () => {
+ test("length is 1", () => {
+ expect(Temporal.PlainTime.prototype.with).toHaveLength(1);
+ });
+
+ test("basic functionality", () => {
+ const plainTime = new Temporal.PlainTime(1, 2, 3).with({ hour: 4, foo: 5, second: 6 });
+ expect(plainTime.hour).toBe(4);
+ expect(plainTime.minute).toBe(2);
+ expect(plainTime.second).toBe(6);
+ });
+
+ test("each property is looked up from the object", () => {
+ for (const property of PLAIN_TIME_PROPERTIES) {
+ const plainTime = new Temporal.PlainTime().with({ [property]: 1 });
+ expect(plainTime[property]).toBe(1);
+ }
+ });
+
+ test("each property is coerced to number", () => {
+ for (const property of PLAIN_TIME_PROPERTIES) {
+ const plainTime = new Temporal.PlainTime().with({ [property]: "1" });
+ expect(plainTime[property]).toBe(1);
+ }
+ });
+
+ test("argument can have a calendar property as long as it's undefined", () => {
+ expect(() => {
+ new Temporal.PlainTime().with({
+ calendar: undefined,
+ });
+ }).not.toThrowWithMessage(TypeError, "Argument must not have a defined calendar property");
+ });
+
+ test("argument can have a timeZone property as long as it's undefined", () => {
+ expect(() => {
+ new Temporal.PlainTime().with({
+ timeZone: undefined,
+ });
+ }).not.toThrowWithMessage(TypeError, "Argument must not have a defined timeZone property");
+ });
+});
+
+describe("errors", () => {
+ test("this value must be a Temporal.PlainTime object", () => {
+ expect(() => {
+ Temporal.PlainTime.prototype.with.call("foo");
+ }).toThrowWithMessage(TypeError, "Not a Temporal.PlainTime object");
+ });
+
+ test("argument is not an object", () => {
+ expect(() => {
+ new Temporal.PlainTime().with("foo");
+ }).toThrowWithMessage(TypeError, "foo is not an object");
+ expect(() => {
+ new Temporal.PlainTime().with(42);
+ }).toThrowWithMessage(TypeError, "42 is not an object");
+ });
+
+ test("options is not an object", () => {
+ expect(() => {
+ new Temporal.PlainTime().with({ hour: 1 }, "foo");
+ }).toThrowWithMessage(TypeError, "Options is not an object");
+ expect(() => {
+ new Temporal.PlainTime().with({ hour: 1 }, 42);
+ }).toThrowWithMessage(TypeError, "Options is not an object");
+ });
+
+ test("invalid overflow option", () => {
+ expect(() => {
+ new Temporal.PlainTime().with({ hour: 1 }, { overflow: "a" });
+ }).toThrowWithMessage(RangeError, "a is not a valid value for option overflow");
+ });
+
+ test("argument is an invalid plain time-like object", () => {
+ expect(() => {
+ new Temporal.PlainTime().with({});
+ }).toThrowWithMessage(TypeError, "Invalid plain time-like object");
+ expect(() => {
+ new Temporal.PlainTime().with({ foo: 1, bar: 2 });
+ }).toThrowWithMessage(TypeError, "Invalid plain time-like object");
+ });
+
+ test("error when coercing property to number", () => {
+ for (const property of PLAIN_TIME_PROPERTIES) {
+ expect(() => {
+ new Temporal.PlainTime().with({
+ [property]: {
+ valueOf() {
+ throw new Error("error occurred");
+ },
+ },
+ });
+ }).toThrowWithMessage(Error, "error occurred");
+ }
+ });
+
+ test("property must be finite", () => {
+ for (const property of PLAIN_TIME_PROPERTIES) {
+ expect(() => {
+ new Temporal.PlainTime().with({ [property]: Infinity });
+ }).toThrowWithMessage(RangeError, "Property must not be Infinity");
+ expect(() => {
+ new Temporal.PlainTime().with({ [property]: -Infinity });
+ }).toThrowWithMessage(RangeError, "Property must not be Infinity");
+ }
+ });
+
+ test("error when getting property", () => {
+ for (const property of PLAIN_TIME_PROPERTIES) {
+ expect(() => {
+ new Temporal.PlainTime().with({
+ get [property]() {
+ throw new Error("error occurred");
+ },
+ });
+ }).toThrowWithMessage(Error, "error occurred");
+ }
+ });
+
+ test("argument must not have a defined calendar property", () => {
+ expect(() => {
+ new Temporal.PlainTime().with({
+ calendar: null,
+ });
+ }).toThrowWithMessage(TypeError, "Argument must not have a defined calendar property");
+ expect(() => {
+ new Temporal.PlainTime().with({
+ calendar: 1,
+ });
+ }).toThrowWithMessage(TypeError, "Argument must not have a defined calendar property");
+ });
+
+ test("argument must not have a defined timeZone property", () => {
+ expect(() => {
+ new Temporal.PlainTime().with({
+ timeZone: null,
+ });
+ }).toThrowWithMessage(TypeError, "Argument must not have a defined timeZone property");
+ expect(() => {
+ new Temporal.PlainTime().with({
+ timeZone: 1,
+ });
+ }).toThrowWithMessage(TypeError, "Argument must not have a defined timeZone property");
+ });
+
+ test("error when getting calendar", () => {
+ expect(() => {
+ new Temporal.PlainTime().with({
+ get calendar() {
+ throw new Error("error occurred");
+ },
+ });
+ }).toThrowWithMessage(Error, "error occurred");
+ });
+
+ test("error when getting timeZone", () => {
+ expect(() => {
+ new Temporal.PlainTime().with({
+ get timeZone() {
+ throw new Error("error occurred");
+ },
+ });
+ }).toThrowWithMessage(Error, "error occurred");
+ });
+
+ test("rejects calendar types", () => {
+ for (const typeWithCalendar of REJECTED_CALENDAR_TYPES_THREE_ARGUMENTS) {
+ expect(() => {
+ new Temporal.PlainTime().with(new typeWithCalendar(1, 1, 1));
+ }).toThrowWithMessage(
+ TypeError,
+ "Argument must not have a defined calendar or timeZone property"
+ );
+ }
+
+ for (const typeWithCalendar of REJECTED_CALENDAR_TYPES_TWO_ARGUMENTS) {
+ expect(() => {
+ new Temporal.PlainTime().with(new typeWithCalendar(1, 1));
+ }).toThrowWithMessage(
+ TypeError,
+ "Argument must not have a defined calendar or timeZone property"
+ );
+ }
+
+ expect(() => {
+ new Temporal.PlainTime().with(new Temporal.ZonedDateTime(1n, {}));
+ }).toThrowWithMessage(
+ TypeError,
+ "Argument must not have a defined calendar or timeZone property"
+ );
+ });
+});