Skip to content

Commit

Permalink
Temporal: Add tests for new yearOfWeek API
Browse files Browse the repository at this point in the history
To be presented for consensus in the November/December TC39 meeting. This
adds tests for a 'yearOfWeek' getter to PlainDate, PlainDateTime, and
ZonedDateTime, for use alongside 'weekOfYear', and tests for a
corresponding method to Calendar.

The tests are basically the existing tests of 'weekOfYear' adapted.

Temporal issue: tc39/proposal-temporal#2405
  • Loading branch information
ptomato committed Nov 30, 2022
1 parent 338063f commit 3775b47
Show file tree
Hide file tree
Showing 58 changed files with 1,509 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.yearofweek
description: >
Calendar.dateFromFields method is called with a null-prototype fields object
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const calendar = TemporalHelpers.calendarCheckFieldsPrototypePollution();
const instance = new Temporal.Calendar("iso8601");
const arg = { year: 2000, month: 5, day: 2, calendar };
instance.yearOfWeek(arg);
assert.sameValue(calendar.dateFromFieldsCallCount, 1, "dateFromFields should be called on the property bag's calendar");
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.yearofweek
description: >
When calendar.fields is undefined, yearOfWeek() doesn't perform an
observable array iteration to convert the property bag to PlainDate
features: [Temporal]
---*/

const calendar = new Temporal.Calendar("iso8601");
calendar.fields = undefined;

const instance = new Temporal.Calendar("iso8601");

// Detect observable array iteration:
const oldIterator = Array.prototype[Symbol.iterator];
Array.prototype[Symbol.iterator] = function () {
throw new Test262Error(`array shouldn't be iterated: ${new Error().stack}`);
};

const arg = { year: 1981, month: 12, day: 15, calendar };

instance.yearOfWeek(arg);

Array.prototype[Symbol.iterator] = oldIterator;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.yearofweek
description: Leap second is a valid ISO string for PlainDate
features: [Temporal]
---*/

const instance = new Temporal.Calendar("iso8601");

let arg = "2016-12-31T23:59:60";
const result1 = instance.yearOfWeek(arg);
assert.sameValue(
result1,
2016,
"leap second is a valid ISO string for PlainDate"
);

arg = { year: 2016, month: 12, day: 31, hour: 23, minute: 59, second: 60 };
const result2 = instance.yearOfWeek(arg);
assert.sameValue(
result2,
2016,
"second: 60 is ignored in property bag for PlainDate"
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.yearofweek
description: A number is converted to a string, then to Temporal.PlainDate
features: [Temporal]
---*/

const instance = new Temporal.Calendar("iso8601");

const arg = 19761118;

const result = instance.yearOfWeek(arg);
assert.sameValue(result, 1976, "19761118 is a valid ISO string for PlainDate");

const numbers = [
1,
-19761118,
1234567890,
];

for (const arg of numbers) {
assert.throws(
RangeError,
() => instance.yearOfWeek(arg),
`Number ${arg} does not convert to a valid ISO string for PlainDate`
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.yearofweek
description: >
A Temporal.Calendar instance passed to yearOfWeek() in a property bag does
not have its 'calendar' property observably checked
features: [Temporal]
---*/

const instance = new Temporal.Calendar("iso8601");

const calendar = new Temporal.Calendar("iso8601");
Object.defineProperty(calendar, "calendar", {
get() {
throw new Test262Error("calendar.calendar should not be accessed");
},
});

let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
instance.yearOfWeek(arg);

arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
instance.yearOfWeek(arg);
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.yearofweek
description: Leap second is a valid ISO string for a calendar in a property bag
features: [Temporal]
---*/

const instance = new Temporal.Calendar("iso8601");

const calendar = "2016-12-31T23:59:60";

let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result1 = instance.yearOfWeek(arg);
assert.sameValue(
result1,
1976,
"leap second is a valid ISO string for calendar"
);

arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
const result2 = instance.yearOfWeek(arg);
assert.sameValue(
result2,
1976,
"leap second is a valid ISO string for calendar (nested property)"
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.yearofweek
description: A number as calendar in a property bag is converted to a string, then to a calendar
features: [Temporal]
---*/

const instance = new Temporal.Calendar("iso8601");

const calendar = 19970327;

let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result1 = instance.yearOfWeek(arg);
assert.sameValue(result1, 1976, "19970327 is a valid ISO string for calendar");

arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
const result2 = instance.yearOfWeek(arg);
assert.sameValue(result2, 1976, "19970327 is a valid ISO string for calendar (nested property)");

const numbers = [
1,
-19970327,
1234567890,
];

for (const calendar of numbers) {
let arg = { year: 1976, monthCode: "M11", day: 18, calendar };
assert.throws(
RangeError,
() => instance.yearOfWeek(arg),
`Number ${calendar} does not convert to a valid ISO string for calendar`
);
arg = { year: 1976, monthCode: "M11", day: 18, calendar: { calendar } };
assert.throws(
RangeError,
() => instance.yearOfWeek(arg),
`Number ${calendar} does not convert to a valid ISO string for calendar (nested property)`
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.yearofweek
description: A calendar ID is valid input for Calendar
features: [Temporal]
---*/

const instance = new Temporal.Calendar("iso8601");

const calendar = "iso8601";

const arg = { year: 1976, monthCode: "M11", day: 18, calendar };
const result = instance.yearOfWeek(arg);
assert.sameValue(result, 1976, `Calendar created from string "${calendar}"`);
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.yearofweek
description: >
Appropriate error thrown when a calendar property from a property bag cannot
be converted to a calendar object or string
features: [BigInt, Symbol, Temporal]
---*/

const timeZone = new Temporal.TimeZone("UTC");
const instance = new Temporal.Calendar("iso8601");

const rangeErrorTests = [
[null, "null"],
[true, "boolean"],
["", "empty string"],
[1, "number that doesn't convert to a valid ISO string"],
[1n, "bigint"],
];

for (const [calendar, description] of rangeErrorTests) {
let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
assert.throws(RangeError, () => instance.yearOfWeek(arg), `${description} does not convert to a valid ISO string`);

arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
assert.throws(RangeError, () => instance.yearOfWeek(arg), `${description} does not convert to a valid ISO string (nested property)`);
}

const typeErrorTests = [
[Symbol(), "symbol"],
[{}, "plain object"], // TypeError due to missing dateFromFields()
[Temporal.Calendar, "Temporal.Calendar, object"], // ditto
[Temporal.Calendar.prototype, "Temporal.Calendar.prototype, object"], // fails brand check in dateFromFields()
];

for (const [calendar, description] of typeErrorTests) {
let arg = { year: 2019, monthCode: "M11", day: 1, calendar };
assert.throws(TypeError, () => instance.yearOfWeek(arg), `${description} is not a valid property bag and does not convert to a string`);

arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar } };
assert.throws(TypeError, () => instance.yearOfWeek(arg), `${description} is not a valid property bag and does not convert to a string (nested property)`);
}

const arg = { year: 2019, monthCode: "M11", day: 1, calendar: { calendar: undefined } };
assert.throws(RangeError, () => instance.yearOfWeek(arg), `nested undefined calendar property is always a RangeError`);
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.yearofweek
description: Negative zero, as an extended year, is rejected
features: [Temporal, arrow-function]
---*/

const invalidStrings = [
"-000000-10-31",
"-000000-10-31T17:45",
"-000000-10-31T17:45Z",
"-000000-10-31T17:45+01:00",
"-000000-10-31T17:45+00:00[UTC]",
];
const instance = new Temporal.Calendar("iso8601");
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.yearOfWeek(arg),
"reject minus zero as extended year"
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.yearofweek
description: Various forms of calendar annotation; critical flag has no effect
features: [Temporal]
---*/

const tests = [
["2000-05-02[u-ca=iso8601]", "without time or time zone"],
["2000-05-02[UTC][u-ca=iso8601]", "with time zone and no time"],
["2000-05-02T15:23[u-ca=iso8601]", "without time zone"],
["2000-05-02T15:23[UTC][u-ca=iso8601]", "with time zone"],
["2000-05-02T15:23[!u-ca=iso8601]", "with ! and no time zone"],
["2000-05-02T15:23[UTC][!u-ca=iso8601]", "with ! and time zone"],
["2000-05-02T15:23[u-ca=iso8601][u-ca=discord]", "second annotation ignored"],
["2000-05-02T15:23[u-ca=iso8601][!u-ca=discord]", "second annotation ignored even with !"],
];

const instance = new Temporal.Calendar("iso8601");

tests.forEach(([arg, description]) => {
const result = instance.yearOfWeek(arg);

assert.sameValue(
result,
2000,
`calendar annotation (${description})`
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.yearofweek
description: Unknown annotations with critical flag are rejected
features: [Temporal]
---*/

const invalidStrings = [
"1970-01-01[!foo=bar]",
"1970-01-01T00:00[!foo=bar]",
"1970-01-01T00:00[UTC][!foo=bar]",
"1970-01-01T00:00[u-ca=iso8601][!foo=bar]",
"1970-01-01T00:00[UTC][!foo=bar][u-ca=iso8601]",
"1970-01-01T00:00[foo=bar][!_foo-bar0=Dont-Ignore-This-99999999999]",
];
const instance = new Temporal.Calendar("iso8601");
invalidStrings.forEach((arg) => {
assert.throws(
RangeError,
() => instance.yearOfWeek(arg),
`reject unknown annotation with critical flag: ${arg}`
);
});
Loading

0 comments on commit 3775b47

Please sign in to comment.