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

Add tests for Temporal.now.plainDateTime #3037

Merged
merged 7 commits into from
Jul 16, 2021
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
82 changes: 82 additions & 0 deletions harness/temporalHelpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: |
This defines helper objects and functions for testing Temporal.
defines: [TemporalHelpers]
features: [Symbol.species, Symbol.iterator, Temporal]
---*/

var TemporalHelpers = {
/*
* Check that any calendar-carrying Temporal object has its [[Calendar]]
* internal slot read by ToTemporalCalendar, and does not fetch the calendar
* by calling getters.
* The custom calendar object is passed in to func() so that it can do its
* own additional assertions involving the calendar if necessary. (Sometimes
* there is nothing to assert as the calendar isn't stored anywhere that can
* be asserted about.)
*/
checkToTemporalCalendarFastPath(func) {
class CalendarFastPathCheck extends Temporal.Calendar {
constructor() {
super("iso8601");
}

toString() {
return "fast-path-check";
}
}
const calendar = new CalendarFastPathCheck();

const plainDate = new Temporal.PlainDate(2000, 5, 2, calendar);
const plainDateTime = new Temporal.PlainDateTime(2000, 5, 2, 12, 34, 56, 987, 654, 321, calendar);
const plainMonthDay = new Temporal.PlainMonthDay(5, 2, calendar);
const plainYearMonth = new Temporal.PlainYearMonth(2000, 5, calendar);
const zonedDateTime = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "UTC", calendar);

[plainDate, plainDateTime, plainMonthDay, plainYearMonth, zonedDateTime].forEach((temporalObject) => {
const actual = [];
const expected = [];

Object.defineProperty(temporalObject, "calendar", {
get() {
actual.push("get calendar");
return calendar;
},
});

func(temporalObject, calendar);
assert.compareArray(actual, expected, "calendar getter not called");
});
},

/*
* specificOffsetTimeZone():
*
* This returns an instance of a custom time zone class, which returns a
* specific custom value from its getOffsetNanosecondsFrom() method. This is
* for the purpose of testing the validation of what this method returns.
*
* It also returns an empty array from getPossibleInstantsFor(), so as to
* trigger calls to getOffsetNanosecondsFor() when used from the
* BuiltinTimeZoneGetInstantFor operation.
*/
specificOffsetTimeZone(offsetValue) {
class SpecificOffsetTimeZone extends Temporal.TimeZone {
constructor(offsetValue) {
super("UTC");
this._offsetValue = offsetValue;
}

getOffsetNanosecondsFor() {
return this._offsetValue;
}

getPossibleInstantsFor() {
return [];
}
}
return new SpecificOffsetTimeZone(offsetValue);
},
};
46 changes: 46 additions & 0 deletions test/built-ins/Temporal/now/plainDateTime/calendar-function.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (C) 2020 Igalia, S.L. All rights reserved.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, originates here: tc39/proposal-temporal@60211b2

// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.now.plaindatetime
description: Behavior when provided calendar value is a function
includes: [compareArray.js]
features: [Temporal]
---*/

const actual = [];
const expected = [
"has timeZone.timeZone",
"get timeZone.getOffsetNanosecondsFor",
"call timeZone.getOffsetNanosecondsFor",
];
const calendar = function() {};
const timeZone = new Proxy({
getOffsetNanosecondsFor(instant) {
actual.push("call timeZone.getOffsetNanosecondsFor");
return -Number(instant.epochNanoseconds % 86400_000_000_000n);
},
}, {
has(target, property) {
actual.push(`has timeZone.${property}`);
return property in target;
},
get(target, property) {
actual.push(`get timeZone.${property}`);
return target[property];
},
});

Object.defineProperty(Temporal.Calendar, "from", {
get() {
actual.push("get Temporal.Calendar.from");
return undefined;
},
});

const result = Temporal.now.plainDateTime(calendar, timeZone);
for (const property of ["hour", "minute", "second", "millisecond", "microsecond", "nanosecond"]) {
assert.sameValue(result[property], 0, property);
}

assert.compareArray(actual, expected);
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (C) 2021 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.now.plaindatetime
description: Forwards error thrown by invoking "toString" property
features: [Temporal]
---*/

var calendar = {
calendar: {
calendar: true,
toString: function() {
throw new Test262Error();
},
}
};

assert.throws(Test262Error, function() {
Temporal.now.plainDateTime(calendar);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (C) 2021 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.now.plaindatetime
description: Forwards error thrown by retrieving value of "calendar" property
features: [Temporal]
---*/

var calendar = {
get calendar() {
throw new Test262Error();
},
};

assert.throws(Test262Error, function() {
Temporal.now.plainDateTime(calendar);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (C) 2021 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.now.plaindatetime
description: Forwards error thrown by checking presence of "calendar" property
features: [Temporal]
---*/

var calendar = new Proxy({}, {
has: function(target, property) {
if (property === 'calendar') {
throw new Test262Error();
}
},
});

assert.throws(Test262Error, function() {
Temporal.now.plainDateTime(calendar);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (C) 2021 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.now.plaindatetime
description: Forwards error thrown by checking presence of nested "calendar" property
features: [Temporal]
---*/

var calendar = {
calendar: new Proxy({}, {
has: function(target, property) {
if (property === 'calendar') {
throw new Test262Error();
}
},
})
};

assert.throws(Test262Error, function() {
Temporal.now.plainDateTime(calendar);
});
61 changes: 61 additions & 0 deletions test/built-ins/Temporal/now/plainDateTime/calendar-object.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright (C) 2020 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.now.plaindatetime
description: Observable interactions with the provided calendar-like object
includes: [compareArray.js]
features: [Temporal]
---*/

const actual = [];
const expected = [
'has calendar.calendar',
'get calendar.calendar',
'has nestedCalendar.calendar',
'get nestedCalendar.Symbol(Symbol.toPrimitive)',
'get nestedCalendar.toString',
'call nestedCalendar.toString'
];
const nestedCalendar = new Proxy({
toString: function() {
actual.push('call nestedCalendar.toString');
return 'iso8601';
}
}, {
has(target, property) {
actual.push(`has nestedCalendar.${String(property)}`);
return property in target;
},
get(target, property) {
actual.push(`get nestedCalendar.${String(property)}`);
return target[property];
},
});
const calendar = new Proxy({
calendar: nestedCalendar,
toString: function() {
actual.push('call calendar.toString');
return 'iso8601';
},
}, {
has(target, property) {
actual.push(`has calendar.${String(property)}`);
return property in target;
},
get(target, property) {
actual.push(`get calendar.${String(property)}`);
return target[property];
},
});

Object.defineProperty(Temporal.Calendar, 'from', {
get() {
actual.push('get Temporal.Calendar.from');
return undefined;
},
});

Temporal.now.plainDateTime(calendar);

assert.compareArray(actual, expected);
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (C) 2021 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.now.plaindatetime
description: Fast path for converting other Temporal objects to Temporal.Calendar by reading internal slots
info: |
sec-temporal.now.plaindatetime step 1:
1. Return ? SystemDateTime(_temporalTimeZoneLike_, _calendar_).
sec-temporal-systemdatetime step 3:
3. Let _calendar_ be ? ToTemporalCalendar(_calendarLike_).
sec-temporal-totemporalcalendar step 1.a:
a. If _temporalCalendarLike_ has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then
i. Return _temporalCalendarLike_.[[Calendar]].
includes: [compareArray.js, temporalHelpers.js]
features: [Temporal]
---*/

TemporalHelpers.checkToTemporalCalendarFastPath((temporalObject, calendar) => {
const result = Temporal.now.plainDateTime(temporalObject);
assert.sameValue(result.calendar, calendar, "Temporal object coerced to calendar");
});
9 changes: 9 additions & 0 deletions test/built-ins/Temporal/now/plainDateTime/extensible.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (C) 2021 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.now.plaindatetime
description: Temporal.now.plainDateTime is extensible.
features: [Temporal]
---*/

assert(Object.isExtensible(Temporal.now.plainDateTime));
25 changes: 25 additions & 0 deletions test/built-ins/Temporal/now/plainDateTime/length.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2020 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.now.plaindatetime
description: The `length` property of Temporal.now.plainDateTime
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.now.plainDateTime, "length", {
value: 1,
writable: false,
enumerable: false,
configurable: true,
});
16 changes: 16 additions & 0 deletions test/built-ins/Temporal/now/plainDateTime/name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (C) 2021 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.now.plainDateTime
description: Temporal.now.plainDateTime.name is "plainDateTime".
includes: [propertyHelper.js]
features: [Temporal]
---*/

assert.sameValue(Temporal.now.plainDateTime.name, 'plainDateTime');

verifyProperty(Temporal.now.plainDateTime, 'name', {
enumerable: false,
writable: false,
configurable: true
});
14 changes: 14 additions & 0 deletions test/built-ins/Temporal/now/plainDateTime/not-a-constructor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (C) 2021 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.now.plaindatetime
description: Temporal.now.plainDateTime does not implement [[Construct]]
includes: [isConstructor.js]
features: [Reflect.construct, Temporal]
---*/

assert.sameValue(isConstructor(Temporal.now.plainDateTime), false, 'isConstructor(Temporal.now.plainDateTime) must return false');

assert.throws(TypeError, () => {
new Temporal.now.plainDateTime();
}, '`new Temporal.now.plainDateTime()` throws TypeError');
14 changes: 14 additions & 0 deletions test/built-ins/Temporal/now/plainDateTime/prop-desc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (C) 2021 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-temporal.now.plaindatetime
description: The "plainDateTime" property of Temporal.now
includes: [propertyHelper.js]
features: [Temporal]
---*/

verifyProperty(Temporal.now, 'plainDateTime', {
enumerable: false,
writable: true,
configurable: true
});
Loading