mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 07:17:35 +00:00
LibJS: Re-implement the Date constructor / prototype for spec compliance
First, this adds a constructor to the Date object to be created from a plain double. This is a first step to removing Core::DateTime as the basis for the Date object. A subsequent commit will remove the now- unused data from the object. Next, this implements the constructor in accordance to the spec. The constructor when NewTarget is undefined no longer allocates a Date on the heap. The other constructor properly uses recently created AOs to handle time zone and ensure the created [[DateValue]] is valid. Other methods on the constructor (Date.now) have not been touched yet. Last, the prototype is reimplemented. Again, we use other AOs to handle time zones and time clipping. Not all prototypes are fixed; most of them are, but a few (e.g. Date.prototype.getTimezoneOffset) were not fixed, but left in a mostly unimplemented state for another commit. In all of the above, spec comments are added. This is a rather large change; but it's tough to do any of these parts individually without breaking everything else.
This commit is contained in:
parent
d31e6b9391
commit
d83ce7dd0b
9 changed files with 501 additions and 485 deletions
|
@ -30,18 +30,3 @@ test("Day as argument", () => {
|
|||
expect(date.getSeconds()).toBe(0);
|
||||
expect(date.getMilliseconds()).toBe(0);
|
||||
});
|
||||
|
||||
test("Make Invalid Date valid again", () => {
|
||||
let date = new Date(2021, 0, 1);
|
||||
date.setDate(NaN);
|
||||
expect(date.getTime()).toBe(NaN);
|
||||
|
||||
date.setDate(16);
|
||||
expect(date.getFullYear()).toBe(2021);
|
||||
expect(date.getMonth()).toBe(0);
|
||||
expect(date.getDate()).toBe(16);
|
||||
expect(date.getHours()).toBe(0);
|
||||
expect(date.getMinutes()).toBe(0);
|
||||
expect(date.getSeconds()).toBe(0);
|
||||
expect(date.getMilliseconds()).toBe(0);
|
||||
});
|
||||
|
|
|
@ -60,28 +60,4 @@ test("NaN or undefined in any arguments", () => {
|
|||
date = new Date(2021, 0, 1);
|
||||
date.setMonth(2021, undefined);
|
||||
expect(date.getTime()).toBe(NaN);
|
||||
|
||||
date.setMonth(3, 16);
|
||||
expect(date.getFullYear()).toBe(2021);
|
||||
expect(date.getMonth()).toBe(3);
|
||||
expect(date.getDate()).toBe(16);
|
||||
expect(date.getHours()).toBe(0);
|
||||
expect(date.getMinutes()).toBe(0);
|
||||
expect(date.getSeconds()).toBe(0);
|
||||
expect(date.getMilliseconds()).toBe(0);
|
||||
});
|
||||
|
||||
test("Make Invalid Date valid again", () => {
|
||||
let date = new Date(2021, 0, 1);
|
||||
date.setMonth(NaN, 3, 16);
|
||||
expect(date.getTime()).toBe(NaN);
|
||||
|
||||
date.setMonth(3, 16);
|
||||
expect(date.getFullYear()).toBe(2021);
|
||||
expect(date.getMonth()).toBe(3);
|
||||
expect(date.getDate()).toBe(16);
|
||||
expect(date.getHours()).toBe(0);
|
||||
expect(date.getMinutes()).toBe(0);
|
||||
expect(date.getSeconds()).toBe(0);
|
||||
expect(date.getMilliseconds()).toBe(0);
|
||||
});
|
||||
|
|
|
@ -15,12 +15,6 @@ describe("errors", () => {
|
|||
}).toThrowWithMessage(TypeError, "Cannot convert BigInt to number");
|
||||
});
|
||||
|
||||
test("time value cannot be clipped", () => {
|
||||
expect(() => {
|
||||
new Date(-8.65e15).toLocaleDateString();
|
||||
}).toThrowWithMessage(RangeError, "Time value must be between -8.64E15 and 8.64E15");
|
||||
});
|
||||
|
||||
test("timeStyle may not be specified", () => {
|
||||
expect(() => {
|
||||
new Date().toLocaleDateString([], { timeStyle: "short" });
|
||||
|
@ -34,6 +28,11 @@ describe("correct behavior", () => {
|
|||
expect(d.toLocaleDateString()).toBe("Invalid Date");
|
||||
});
|
||||
|
||||
test("time clip", () => {
|
||||
const d = new Date(-8.65e15);
|
||||
expect(d.toLocaleDateString()).toBe("Invalid Date");
|
||||
});
|
||||
|
||||
const d0 = new Date(Date.UTC(2021, 11, 7, 17, 40, 50, 456));
|
||||
const d1 = new Date(Date.UTC(1989, 0, 23, 7, 8, 9, 45));
|
||||
|
||||
|
|
|
@ -14,12 +14,6 @@ describe("errors", () => {
|
|||
new Date(1n).toLocaleString();
|
||||
}).toThrowWithMessage(TypeError, "Cannot convert BigInt to number");
|
||||
});
|
||||
|
||||
test("time value cannot be clipped", () => {
|
||||
expect(() => {
|
||||
new Date(-8.65e15).toLocaleString();
|
||||
}).toThrowWithMessage(RangeError, "Time value must be between -8.64E15 and 8.64E15");
|
||||
});
|
||||
});
|
||||
|
||||
describe("correct behavior", () => {
|
||||
|
@ -28,6 +22,11 @@ describe("correct behavior", () => {
|
|||
expect(d.toLocaleString()).toBe("Invalid Date");
|
||||
});
|
||||
|
||||
test("time clip", () => {
|
||||
const d = new Date(-8.65e15);
|
||||
expect(d.toLocaleString()).toBe("Invalid Date");
|
||||
});
|
||||
|
||||
const d0 = new Date(Date.UTC(2021, 11, 7, 17, 40, 50, 456));
|
||||
const d1 = new Date(Date.UTC(1989, 0, 23, 7, 8, 9, 45));
|
||||
|
||||
|
|
|
@ -15,12 +15,6 @@ describe("errors", () => {
|
|||
}).toThrowWithMessage(TypeError, "Cannot convert BigInt to number");
|
||||
});
|
||||
|
||||
test("time value cannot be clipped", () => {
|
||||
expect(() => {
|
||||
new Date(-8.65e15).toLocaleTimeString();
|
||||
}).toThrowWithMessage(RangeError, "Time value must be between -8.64E15 and 8.64E15");
|
||||
});
|
||||
|
||||
test("dateStyle may not be specified", () => {
|
||||
expect(() => {
|
||||
new Date().toLocaleTimeString([], { dateStyle: "short" });
|
||||
|
@ -34,6 +28,11 @@ describe("correct behavior", () => {
|
|||
expect(d.toLocaleTimeString()).toBe("Invalid Date");
|
||||
});
|
||||
|
||||
test("time clip", () => {
|
||||
const d = new Date(-8.65e15);
|
||||
expect(d.toLocaleTimeString()).toBe("Invalid Date");
|
||||
});
|
||||
|
||||
const d0 = new Date(Date.UTC(2021, 11, 7, 17, 40, 50, 456));
|
||||
const d1 = new Date(Date.UTC(1989, 0, 23, 7, 8, 9, 45));
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue