mirror of https://github.com/tc39/test262.git
Temporal operation NanosecondsToDays: Test infinite or arbitrary-length observable loops in Duration and ZonedDateTime
This commit is contained in:
parent
6fcebf2f85
commit
09f863d8c3
|
@ -1382,6 +1382,20 @@ var TemporalHelpers = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* observeMethod(calls, object, propertyName, value):
|
||||||
|
*
|
||||||
|
* Defines an own property @object.@propertyName with value @value, that
|
||||||
|
* will log any calls of @value to the array @calls.
|
||||||
|
*/
|
||||||
|
observeMethod(calls, object, propertyName, objectName = "") {
|
||||||
|
const method = object[propertyName];
|
||||||
|
object[propertyName] = function () {
|
||||||
|
calls.push(`call ${formatPropertyName(propertyName, objectName)}`);
|
||||||
|
return method.apply(object, arguments);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used for substituteMethod to indicate default behavior instead of a
|
* Used for substituteMethod to indicate default behavior instead of a
|
||||||
* substituted value
|
* substituted value
|
||||||
|
|
58
test/built-ins/Temporal/Duration/prototype/add/nanoseconds-to-days-loop-indefinitely-1.js
vendored
Normal file
58
test/built-ins/Temporal/Duration/prototype/add/nanoseconds-to-days-loop-indefinitely-1.js
vendored
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// 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.duration.prototype.add
|
||||||
|
description: >
|
||||||
|
NanosecondsToDays can loop arbitrarily long, performing observable operations each iteration.
|
||||||
|
info: |
|
||||||
|
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||||
|
|
||||||
|
...
|
||||||
|
15. If sign is 1, then
|
||||||
|
a. Repeat, while days > 0 and intermediateNs > endNs,
|
||||||
|
i. Set days to days - 1.
|
||||||
|
ii. Set intermediateNs to ℝ(? AddZonedDateTime(ℤ(startNs), relativeTo.[[TimeZone]],
|
||||||
|
relativeTo.[[Calendar]], 0, 0, 0, days, 0, 0, 0, 0, 0, 0)).
|
||||||
|
...
|
||||||
|
includes: [temporalHelpers.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const calls = [];
|
||||||
|
const duration = Temporal.Duration.from({ days: 1 });
|
||||||
|
|
||||||
|
function createRelativeTo(count) {
|
||||||
|
const tz = new Temporal.TimeZone("UTC");
|
||||||
|
// Record calls in calls[]
|
||||||
|
TemporalHelpers.observeMethod(calls, tz, "getPossibleInstantsFor");
|
||||||
|
const cal = new Temporal.Calendar("iso8601");
|
||||||
|
// Return _count_ days for the second call to dateUntil, behaving normally after
|
||||||
|
TemporalHelpers.substituteMethod(cal, "dateUntil", [
|
||||||
|
TemporalHelpers.SUBSTITUTE_SKIP,
|
||||||
|
Temporal.Duration.from({ days: count }),
|
||||||
|
]);
|
||||||
|
return new Temporal.ZonedDateTime(0n, tz, cal);
|
||||||
|
}
|
||||||
|
|
||||||
|
let zdt = createRelativeTo(200);
|
||||||
|
calls.splice(0); // Reset calls list after ZonedDateTime construction
|
||||||
|
duration.add(duration, {
|
||||||
|
relativeTo: zdt,
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
200 + 2,
|
||||||
|
"Expected duration.add to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
||||||
|
|
||||||
|
zdt = createRelativeTo(300);
|
||||||
|
calls.splice(0); // Reset calls list after previous loop + ZonedDateTime construction
|
||||||
|
duration.add(duration, {
|
||||||
|
relativeTo: zdt,
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
300 + 2,
|
||||||
|
"Expected duration.add to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
71
test/built-ins/Temporal/Duration/prototype/add/nanoseconds-to-days-loop-indefinitely-2.js
vendored
Normal file
71
test/built-ins/Temporal/Duration/prototype/add/nanoseconds-to-days-loop-indefinitely-2.js
vendored
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
// 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.duration.prototype.add
|
||||||
|
description: >
|
||||||
|
NanosecondsToDays can loop infinitely.
|
||||||
|
info: |
|
||||||
|
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||||
|
|
||||||
|
...
|
||||||
|
18. Repeat, while done is false,
|
||||||
|
a. Let oneDayFartherNs be ℝ(? AddZonedDateTime(ℤ(intermediateNs), relativeTo.[[TimeZone]],
|
||||||
|
relativeTo.[[Calendar]], 0, 0, 0, sign, 0, 0, 0, 0, 0, 0)).
|
||||||
|
b. Set dayLengthNs to oneDayFartherNs - intermediateNs.
|
||||||
|
c. If (nanoseconds - dayLengthNs) × sign ≥ 0, then
|
||||||
|
i. Set nanoseconds to nanoseconds - dayLengthNs.
|
||||||
|
ii. Set intermediateNs to oneDayFartherNs.
|
||||||
|
iii. Set days to days + sign.
|
||||||
|
d. Else,
|
||||||
|
i. Set done to true.
|
||||||
|
includes: [temporalHelpers.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const calls = [];
|
||||||
|
const duration = Temporal.Duration.from({ days: 1 });
|
||||||
|
|
||||||
|
function createRelativeTo(count) {
|
||||||
|
const dayLengthNs = 86400000000000n;
|
||||||
|
const dayInstant = new Temporal.Instant(dayLengthNs);
|
||||||
|
const substitutions = [];
|
||||||
|
const timeZone = new Temporal.TimeZone("UTC");
|
||||||
|
// Return constant value for first _count_ calls
|
||||||
|
TemporalHelpers.substituteMethod(
|
||||||
|
timeZone,
|
||||||
|
"getPossibleInstantsFor",
|
||||||
|
substitutions
|
||||||
|
);
|
||||||
|
substitutions.length = count;
|
||||||
|
let i = 0;
|
||||||
|
for (i = 0; i < substitutions.length; i++) {
|
||||||
|
// (this value)
|
||||||
|
substitutions[i] = [dayInstant];
|
||||||
|
}
|
||||||
|
// Record calls in calls[]
|
||||||
|
TemporalHelpers.observeMethod(calls, timeZone, "getPossibleInstantsFor");
|
||||||
|
return new Temporal.ZonedDateTime(0n, timeZone);
|
||||||
|
}
|
||||||
|
|
||||||
|
let zdt = createRelativeTo(200);
|
||||||
|
calls.splice(0); // Reset calls list after ZonedDateTime construction
|
||||||
|
duration.add(duration, {
|
||||||
|
relativeTo: zdt,
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
200 + 1,
|
||||||
|
"Expected duration.add to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
||||||
|
|
||||||
|
zdt = createRelativeTo(300);
|
||||||
|
calls.splice(0); // Reset calls list after previous loop + ZonedDateTime construction
|
||||||
|
duration.add(duration, {
|
||||||
|
relativeTo: zdt,
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
300 + 1,
|
||||||
|
"Expected duration.add to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
|
@ -1,10 +1,9 @@
|
||||||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
/*---
|
/*---
|
||||||
esid: sec-temporal.duration.prototype.round
|
esid: sec-temporal.duration.prototype.round
|
||||||
description: >
|
description: >
|
||||||
NanosecondsToDays can loop indefinitely.
|
NanosecondsToDays can loop arbitrarily long, performing observable operations each iteration.
|
||||||
info: |
|
info: |
|
||||||
NanosecondsToDays ( nanoseconds, relativeTo )
|
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||||
|
|
||||||
|
@ -19,54 +18,41 @@ includes: [temporalHelpers.js]
|
||||||
features: [Temporal]
|
features: [Temporal]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
// Intentionally not Test262Error to ensure assertion errors are correctly propagated.
|
const calls = [];
|
||||||
class StopExecution extends Error {}
|
const duration = Temporal.Duration.from({ days: 1 });
|
||||||
|
|
||||||
const stopAt = 1000;
|
function createRelativeTo(count) {
|
||||||
|
const tz = new Temporal.TimeZone("UTC");
|
||||||
|
// Record calls in calls[]
|
||||||
|
TemporalHelpers.observeMethod(calls, tz, "getPossibleInstantsFor");
|
||||||
|
const cal = new Temporal.Calendar("iso8601");
|
||||||
|
// Return _count_ days for the first call to dateUntil, behaving normally after
|
||||||
|
TemporalHelpers.substituteMethod(cal, "dateUntil", [
|
||||||
|
Temporal.Duration.from({ days: count }),
|
||||||
|
]);
|
||||||
|
return new Temporal.ZonedDateTime(0n, tz, cal);
|
||||||
|
}
|
||||||
|
|
||||||
// Always add two days to the start date, this ensures the intermediate date
|
let zdt = createRelativeTo(200);
|
||||||
// is larger than the end date.
|
calls.splice(0); // Reset calls list after ZonedDateTime construction
|
||||||
let twoDays = Temporal.Duration.from({days: 2});
|
duration.round({
|
||||||
|
|
||||||
// Number of calls to dateAdd.
|
|
||||||
let count = 0;
|
|
||||||
|
|
||||||
let cal = new class extends Temporal.Calendar {
|
|
||||||
// Set `days` to a number larger than `Number.MAX_SAFE_INTEGER`.
|
|
||||||
dateUntil(start, end, options) {
|
|
||||||
return Temporal.Duration.from({days: Number.MAX_VALUE});
|
|
||||||
}
|
|
||||||
|
|
||||||
dateAdd(date, duration, options) {
|
|
||||||
// Stop when we've reached the test limit.
|
|
||||||
count += 1;
|
|
||||||
if (count === stopAt) {
|
|
||||||
throw new StopExecution();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count === 1) {
|
|
||||||
return Temporal.Calendar.prototype.dateAdd.call(this, date, duration, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
TemporalHelpers.assertPlainDate(date, 1970, 1, "M01", 1);
|
|
||||||
|
|
||||||
TemporalHelpers.assertDuration(
|
|
||||||
duration,
|
|
||||||
0, 0, 0, Number.MAX_VALUE,
|
|
||||||
0, 0, 0,
|
|
||||||
0, 0, 0,
|
|
||||||
);
|
|
||||||
|
|
||||||
return Temporal.Calendar.prototype.dateAdd.call(this, date, twoDays, options);
|
|
||||||
}
|
|
||||||
}("iso8601");
|
|
||||||
|
|
||||||
let zdt = new Temporal.ZonedDateTime(0n, "UTC", cal);
|
|
||||||
let duration = Temporal.Duration.from({days: 1});
|
|
||||||
let options = {
|
|
||||||
largestUnit: "days",
|
largestUnit: "days",
|
||||||
relativeTo: zdt,
|
relativeTo: zdt,
|
||||||
};
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
200 + 2,
|
||||||
|
"Expected duration.round to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
||||||
|
|
||||||
assert.throws(StopExecution, () => duration.round(options));
|
zdt = createRelativeTo(300);
|
||||||
assert.sameValue(count, stopAt);
|
calls.splice(0); // Reset calls list after previous loop + ZonedDateTime construction
|
||||||
|
duration.round({
|
||||||
|
largestUnit: "days",
|
||||||
|
relativeTo: zdt,
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
300 + 2,
|
||||||
|
"Expected duration.round to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
// Copyright (C) 2022 André Bargull. All rights reserved.
|
// Copyright (C) 2022 André Bargull. All rights reserved.
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
/*---
|
/*---
|
||||||
esid: sec-temporal.duration.prototype.round
|
esid: sec-temporal.duration.prototype.round
|
||||||
description: >
|
description: >
|
||||||
NanosecondsToDays can loop indefinitely.
|
NanosecondsToDays can loop infinitely.
|
||||||
info: |
|
info: |
|
||||||
NanosecondsToDays ( nanoseconds, relativeTo )
|
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||||
|
|
||||||
|
@ -23,43 +22,51 @@ includes: [temporalHelpers.js]
|
||||||
features: [Temporal]
|
features: [Temporal]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
// Intentionally not Test262Error to ensure assertion errors are correctly propagated.
|
const calls = [];
|
||||||
class StopExecution extends Error {}
|
const duration = Temporal.Duration.from({ days: 1 });
|
||||||
|
|
||||||
const stopAt = 1000;
|
function createRelativeTo(count) {
|
||||||
|
const dayLengthNs = 86400000000000n;
|
||||||
// Number of calls to getPossibleInstantsFor.
|
const dayInstant = new Temporal.Instant(dayLengthNs);
|
||||||
let count = 0;
|
const substitutions = [];
|
||||||
|
const timeZone = new Temporal.TimeZone("UTC");
|
||||||
// UTC time zones so we don't have to worry about time zone offsets.
|
// Return constant value for first _count_ calls
|
||||||
let tz = new class extends Temporal.TimeZone {
|
TemporalHelpers.substituteMethod(
|
||||||
getPossibleInstantsFor(dt) {
|
timeZone,
|
||||||
// Stop when we've reached the test limit.
|
"getPossibleInstantsFor",
|
||||||
count += 1;
|
substitutions
|
||||||
if (count === stopAt) {
|
);
|
||||||
throw new StopExecution();
|
substitutions.length = count;
|
||||||
}
|
let i = 0;
|
||||||
|
for (i = 0; i < substitutions.length; i++) {
|
||||||
if (count < 4) {
|
// (this value)
|
||||||
// The first couple calls request the instant for 1970-01-02.
|
substitutions[i] = [dayInstant];
|
||||||
TemporalHelpers.assertPlainDateTime(dt, 1970, 1, "M01", 2, 0, 0, 0, 0, 0, 0);
|
|
||||||
} else {
|
|
||||||
// Later on the instant for 1970-01-03 is requested.
|
|
||||||
TemporalHelpers.assertPlainDateTime(dt, 1970, 1, "M01", 3, 0, 0, 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always return "1970-01-02T00:00:00Z". This leads to iterating indefinitely
|
|
||||||
// in NanosecondsToDays.
|
|
||||||
return [new Temporal.Instant(86400000000000n)];
|
|
||||||
}
|
}
|
||||||
}("UTC");
|
// Record calls in calls[]
|
||||||
|
TemporalHelpers.observeMethod(calls, timeZone, "getPossibleInstantsFor");
|
||||||
|
return new Temporal.ZonedDateTime(0n, timeZone);
|
||||||
|
}
|
||||||
|
|
||||||
let zdt = new Temporal.ZonedDateTime(0n, tz);
|
let zdt = createRelativeTo(200);
|
||||||
let duration = Temporal.Duration.from({days: 1});
|
calls.splice(0); // Reset calls list after ZonedDateTime construction
|
||||||
let options = {
|
duration.round({
|
||||||
smallestUnit: "days",
|
smallestUnit: "days",
|
||||||
relativeTo: zdt,
|
relativeTo: zdt,
|
||||||
};
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
200 + 1,
|
||||||
|
"Expected duration.round to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
||||||
|
|
||||||
assert.throws(StopExecution, () => duration.round(options));
|
zdt = createRelativeTo(300);
|
||||||
assert.sameValue(count, stopAt);
|
calls.splice(0); // Reset calls list after previous loop + ZonedDateTime construction
|
||||||
|
duration.round({
|
||||||
|
smallestUnit: "days",
|
||||||
|
relativeTo: zdt,
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
300 + 1,
|
||||||
|
"Expected duration.round to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
||||||
|
|
59
test/built-ins/Temporal/Duration/prototype/subtract/nanoseconds-to-days-loop-indefinitely-1.js
vendored
Normal file
59
test/built-ins/Temporal/Duration/prototype/subtract/nanoseconds-to-days-loop-indefinitely-1.js
vendored
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
// 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.duration.prototype.subtract
|
||||||
|
description: >
|
||||||
|
NanosecondsToDays can loop arbitrarily long, performing observable operations each iteration.
|
||||||
|
info: |
|
||||||
|
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||||
|
|
||||||
|
...
|
||||||
|
15. If sign is 1, then
|
||||||
|
a. Repeat, while days > 0 and intermediateNs > endNs,
|
||||||
|
i. Set days to days - 1.
|
||||||
|
ii. Set intermediateNs to ℝ(? AddZonedDateTime(ℤ(startNs), relativeTo.[[TimeZone]],
|
||||||
|
relativeTo.[[Calendar]], 0, 0, 0, days, 0, 0, 0, 0, 0, 0)).
|
||||||
|
...
|
||||||
|
includes: [temporalHelpers.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const calls = [];
|
||||||
|
const duration = Temporal.Duration.from({ days: 1 });
|
||||||
|
const other = Temporal.Duration.from({ hours: 1 });
|
||||||
|
|
||||||
|
function createRelativeTo(count) {
|
||||||
|
const tz = new Temporal.TimeZone("UTC");
|
||||||
|
// Record calls in calls[]
|
||||||
|
TemporalHelpers.observeMethod(calls, tz, "getPossibleInstantsFor");
|
||||||
|
const cal = new Temporal.Calendar("iso8601");
|
||||||
|
// Return _count_ days for the second call to dateUntil, behaving normally after
|
||||||
|
TemporalHelpers.substituteMethod(cal, "dateUntil", [
|
||||||
|
TemporalHelpers.SUBSTITUTE_SKIP,
|
||||||
|
Temporal.Duration.from({ days: count }),
|
||||||
|
]);
|
||||||
|
return new Temporal.ZonedDateTime(0n, tz, cal);
|
||||||
|
}
|
||||||
|
|
||||||
|
let zdt = createRelativeTo(200);
|
||||||
|
calls.splice(0); // Reset calls list after ZonedDateTime construction
|
||||||
|
duration.subtract(other, {
|
||||||
|
relativeTo: zdt,
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
200 + 2,
|
||||||
|
"Expected duration.subtract to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
||||||
|
|
||||||
|
zdt = createRelativeTo(300);
|
||||||
|
calls.splice(0); // Reset calls list after previous loop + ZonedDateTime construction
|
||||||
|
duration.subtract(other, {
|
||||||
|
relativeTo: zdt,
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
300 + 2,
|
||||||
|
"Expected duration.subtract to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
71
test/built-ins/Temporal/Duration/prototype/subtract/nanoseconds-to-days-loop-indefinitely-2.js
vendored
Normal file
71
test/built-ins/Temporal/Duration/prototype/subtract/nanoseconds-to-days-loop-indefinitely-2.js
vendored
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
// 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.duration.prototype.subtract
|
||||||
|
description: >
|
||||||
|
NanosecondsToDays can loop infinitely.
|
||||||
|
info: |
|
||||||
|
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||||
|
|
||||||
|
...
|
||||||
|
18. Repeat, while done is false,
|
||||||
|
a. Let oneDayFartherNs be ℝ(? AddZonedDateTime(ℤ(intermediateNs), relativeTo.[[TimeZone]],
|
||||||
|
relativeTo.[[Calendar]], 0, 0, 0, sign, 0, 0, 0, 0, 0, 0)).
|
||||||
|
b. Set dayLengthNs to oneDayFartherNs - intermediateNs.
|
||||||
|
c. If (nanoseconds - dayLengthNs) × sign ≥ 0, then
|
||||||
|
i. Set nanoseconds to nanoseconds - dayLengthNs.
|
||||||
|
ii. Set intermediateNs to oneDayFartherNs.
|
||||||
|
iii. Set days to days + sign.
|
||||||
|
d. Else,
|
||||||
|
i. Set done to true.
|
||||||
|
includes: [temporalHelpers.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const calls = [];
|
||||||
|
const duration = Temporal.Duration.from({ days: 1 });
|
||||||
|
|
||||||
|
function createRelativeTo(count) {
|
||||||
|
const dayLengthNs = 86400000000000n;
|
||||||
|
const dayInstant = new Temporal.Instant(dayLengthNs);
|
||||||
|
const substitutions = [];
|
||||||
|
const timeZone = new Temporal.TimeZone("UTC");
|
||||||
|
// Return constant value for first _count_ calls
|
||||||
|
TemporalHelpers.substituteMethod(
|
||||||
|
timeZone,
|
||||||
|
"getPossibleInstantsFor",
|
||||||
|
substitutions
|
||||||
|
);
|
||||||
|
substitutions.length = count;
|
||||||
|
let i = 0;
|
||||||
|
for (i = 0; i < substitutions.length; i++) {
|
||||||
|
// (this value)
|
||||||
|
substitutions[i] = [dayInstant];
|
||||||
|
}
|
||||||
|
// Record calls in calls[]
|
||||||
|
TemporalHelpers.observeMethod(calls, timeZone, "getPossibleInstantsFor");
|
||||||
|
return new Temporal.ZonedDateTime(0n, timeZone);
|
||||||
|
}
|
||||||
|
|
||||||
|
let zdt = createRelativeTo(200);
|
||||||
|
calls.splice(0); // Reset calls list after ZonedDateTime construction
|
||||||
|
duration.subtract(duration, {
|
||||||
|
relativeTo: zdt,
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
200 + 1,
|
||||||
|
"Expected duration.subtract to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
||||||
|
|
||||||
|
zdt = createRelativeTo(300);
|
||||||
|
calls.splice(0); // Reset calls list after previous loop + ZonedDateTime construction
|
||||||
|
duration.subtract(duration, {
|
||||||
|
relativeTo: zdt,
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
300 + 1,
|
||||||
|
"Expected duration.subtract to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
59
test/built-ins/Temporal/Duration/prototype/total/nanoseconds-to-days-loop-indefinitely-1.js
vendored
Normal file
59
test/built-ins/Temporal/Duration/prototype/total/nanoseconds-to-days-loop-indefinitely-1.js
vendored
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
// 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.duration.prototype.total
|
||||||
|
description: >
|
||||||
|
NanosecondsToDays can loop arbitrarily long, performing observable operations each iteration.
|
||||||
|
info: |
|
||||||
|
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||||
|
|
||||||
|
...
|
||||||
|
15. If sign is 1, then
|
||||||
|
a. Repeat, while days > 0 and intermediateNs > endNs,
|
||||||
|
i. Set days to days - 1.
|
||||||
|
ii. Set intermediateNs to ℝ(? AddZonedDateTime(ℤ(startNs), relativeTo.[[TimeZone]],
|
||||||
|
relativeTo.[[Calendar]], 0, 0, 0, days, 0, 0, 0, 0, 0, 0)).
|
||||||
|
...
|
||||||
|
includes: [temporalHelpers.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const calls = [];
|
||||||
|
const duration = Temporal.Duration.from({ days: 1 });
|
||||||
|
|
||||||
|
function createRelativeTo(count) {
|
||||||
|
const tz = new Temporal.TimeZone("UTC");
|
||||||
|
// Record calls in calls[]
|
||||||
|
TemporalHelpers.observeMethod(calls, tz, "getPossibleInstantsFor");
|
||||||
|
const cal = new Temporal.Calendar("iso8601");
|
||||||
|
// Return _count_ days for the first call to dateUntil, behaving normally after
|
||||||
|
TemporalHelpers.substituteMethod(cal, "dateUntil", [
|
||||||
|
Temporal.Duration.from({ days: count }),
|
||||||
|
]);
|
||||||
|
return new Temporal.ZonedDateTime(0n, tz, cal);
|
||||||
|
}
|
||||||
|
|
||||||
|
let zdt = createRelativeTo(200);
|
||||||
|
calls.splice(0); // Reset calls list after ZonedDateTime construction
|
||||||
|
duration.total({
|
||||||
|
unit: "day",
|
||||||
|
relativeTo: zdt,
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
200 + 3,
|
||||||
|
"Expected duration.total to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
||||||
|
|
||||||
|
zdt = createRelativeTo(300);
|
||||||
|
calls.splice(0); // Reset calls list after previous loop + ZonedDateTime construction
|
||||||
|
duration.total({
|
||||||
|
unit: "day",
|
||||||
|
relativeTo: zdt,
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
300 + 3,
|
||||||
|
"Expected duration.total to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
73
test/built-ins/Temporal/Duration/prototype/total/nanoseconds-to-days-loop-indefinitely-2.js
vendored
Normal file
73
test/built-ins/Temporal/Duration/prototype/total/nanoseconds-to-days-loop-indefinitely-2.js
vendored
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
// 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.duration.prototype.total
|
||||||
|
description: >
|
||||||
|
NanosecondsToDays can loop infinitely.
|
||||||
|
info: |
|
||||||
|
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||||
|
|
||||||
|
...
|
||||||
|
18. Repeat, while done is false,
|
||||||
|
a. Let oneDayFartherNs be ℝ(? AddZonedDateTime(ℤ(intermediateNs), relativeTo.[[TimeZone]],
|
||||||
|
relativeTo.[[Calendar]], 0, 0, 0, sign, 0, 0, 0, 0, 0, 0)).
|
||||||
|
b. Set dayLengthNs to oneDayFartherNs - intermediateNs.
|
||||||
|
c. If (nanoseconds - dayLengthNs) × sign ≥ 0, then
|
||||||
|
i. Set nanoseconds to nanoseconds - dayLengthNs.
|
||||||
|
ii. Set intermediateNs to oneDayFartherNs.
|
||||||
|
iii. Set days to days + sign.
|
||||||
|
d. Else,
|
||||||
|
i. Set done to true.
|
||||||
|
includes: [temporalHelpers.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const calls = [];
|
||||||
|
const duration = Temporal.Duration.from({ days: 1 });
|
||||||
|
|
||||||
|
function createRelativeTo(count) {
|
||||||
|
const dayLengthNs = 86400000000000n;
|
||||||
|
const dayInstant = new Temporal.Instant(dayLengthNs);
|
||||||
|
const substitutions = [];
|
||||||
|
const timeZone = new Temporal.TimeZone("UTC");
|
||||||
|
// Return constant value for first _count_ calls
|
||||||
|
TemporalHelpers.substituteMethod(
|
||||||
|
timeZone,
|
||||||
|
"getPossibleInstantsFor",
|
||||||
|
substitutions
|
||||||
|
);
|
||||||
|
substitutions.length = count;
|
||||||
|
let i = 0;
|
||||||
|
for (i = 0; i < substitutions.length; i++) {
|
||||||
|
// (this value)
|
||||||
|
substitutions[i] = [dayInstant];
|
||||||
|
}
|
||||||
|
// Record calls in calls[]
|
||||||
|
TemporalHelpers.observeMethod(calls, timeZone, "getPossibleInstantsFor");
|
||||||
|
return new Temporal.ZonedDateTime(0n, timeZone);
|
||||||
|
}
|
||||||
|
|
||||||
|
let zdt = createRelativeTo(200);
|
||||||
|
calls.splice(0); // Reset calls list after ZonedDateTime construction
|
||||||
|
duration.total({
|
||||||
|
unit: "day",
|
||||||
|
relativeTo: zdt,
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
200 + 2,
|
||||||
|
"Expected duration.total to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
||||||
|
|
||||||
|
zdt = createRelativeTo(300);
|
||||||
|
calls.splice(0); // Reset calls list after previous loop + ZonedDateTime construction
|
||||||
|
duration.total({
|
||||||
|
unit: "day",
|
||||||
|
relativeTo: zdt,
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
300 + 2,
|
||||||
|
"Expected duration.total to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
59
test/built-ins/Temporal/ZonedDateTime/prototype/since/nanoseconds-to-days-loop-indefinitely-1.js
vendored
Normal file
59
test/built-ins/Temporal/ZonedDateTime/prototype/since/nanoseconds-to-days-loop-indefinitely-1.js
vendored
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
// 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.zoneddatetime.prototype.since
|
||||||
|
description: >
|
||||||
|
NanosecondsToDays can loop arbitrarily long, performing observable operations each iteration.
|
||||||
|
info: |
|
||||||
|
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||||
|
|
||||||
|
...
|
||||||
|
15. If sign is 1, then
|
||||||
|
a. Repeat, while days > 0 and intermediateNs > endNs,
|
||||||
|
i. Set days to days - 1.
|
||||||
|
ii. Set intermediateNs to ℝ(? AddZonedDateTime(ℤ(startNs), relativeTo.[[TimeZone]],
|
||||||
|
relativeTo.[[Calendar]], 0, 0, 0, days, 0, 0, 0, 0, 0, 0)).
|
||||||
|
...
|
||||||
|
includes: [temporalHelpers.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const calls = [];
|
||||||
|
const dayLengthNs = 86400000000000n;
|
||||||
|
const other = new Temporal.ZonedDateTime(dayLengthNs, "UTC", "iso8601");
|
||||||
|
|
||||||
|
function createRelativeTo(count) {
|
||||||
|
const tz = new Temporal.TimeZone("UTC");
|
||||||
|
// Record calls in calls[]
|
||||||
|
TemporalHelpers.observeMethod(calls, tz, "getPossibleInstantsFor");
|
||||||
|
const cal = new Temporal.Calendar("iso8601");
|
||||||
|
// Return _count_ days for the second call to dateUntil, behaving normally after
|
||||||
|
TemporalHelpers.substituteMethod(cal, "dateUntil", [
|
||||||
|
TemporalHelpers.SUBSTITUTE_SKIP,
|
||||||
|
Temporal.Duration.from({ days: count }),
|
||||||
|
]);
|
||||||
|
return new Temporal.ZonedDateTime(0n, tz, cal);
|
||||||
|
}
|
||||||
|
|
||||||
|
let zdt = createRelativeTo(200);
|
||||||
|
calls.splice(0); // Reset calls list after ZonedDateTime construction
|
||||||
|
zdt.since(other, {
|
||||||
|
largestUnit: "day",
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
200 + 1,
|
||||||
|
"Expected ZonedDateTime.since to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
||||||
|
|
||||||
|
zdt = createRelativeTo(300);
|
||||||
|
calls.splice(0); // Reset calls list after previous loop + ZonedDateTime construction
|
||||||
|
zdt.since(other, {
|
||||||
|
largestUnit: "day",
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
300 + 1,
|
||||||
|
"Expected ZonedDateTime.since to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
71
test/built-ins/Temporal/ZonedDateTime/prototype/since/nanoseconds-to-days-loop-indefinitely-2.js
vendored
Normal file
71
test/built-ins/Temporal/ZonedDateTime/prototype/since/nanoseconds-to-days-loop-indefinitely-2.js
vendored
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
// 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.zoneddatetime.prototype.since
|
||||||
|
description: >
|
||||||
|
NanosecondsToDays can loop infinitely.
|
||||||
|
info: |
|
||||||
|
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||||
|
|
||||||
|
...
|
||||||
|
18. Repeat, while done is false,
|
||||||
|
a. Let oneDayFartherNs be ℝ(? AddZonedDateTime(ℤ(intermediateNs), relativeTo.[[TimeZone]],
|
||||||
|
relativeTo.[[Calendar]], 0, 0, 0, sign, 0, 0, 0, 0, 0, 0)).
|
||||||
|
b. Set dayLengthNs to oneDayFartherNs - intermediateNs.
|
||||||
|
c. If (nanoseconds - dayLengthNs) × sign ≥ 0, then
|
||||||
|
i. Set nanoseconds to nanoseconds - dayLengthNs.
|
||||||
|
ii. Set intermediateNs to oneDayFartherNs.
|
||||||
|
iii. Set days to days + sign.
|
||||||
|
d. Else,
|
||||||
|
i. Set done to true.
|
||||||
|
includes: [temporalHelpers.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const calls = [];
|
||||||
|
const dayLengthNs = 86400000000000n;
|
||||||
|
const other = new Temporal.ZonedDateTime(dayLengthNs, "UTC", "iso8601");
|
||||||
|
|
||||||
|
function createRelativeTo(count) {
|
||||||
|
const dayInstant = new Temporal.Instant(dayLengthNs);
|
||||||
|
const substitutions = [];
|
||||||
|
const timeZone = new Temporal.TimeZone("UTC");
|
||||||
|
// Return constant value for first _count_ calls
|
||||||
|
TemporalHelpers.substituteMethod(
|
||||||
|
timeZone,
|
||||||
|
"getPossibleInstantsFor",
|
||||||
|
substitutions
|
||||||
|
);
|
||||||
|
substitutions.length = count;
|
||||||
|
let i = 0;
|
||||||
|
for (i = 0; i < substitutions.length; i++) {
|
||||||
|
// (this value)
|
||||||
|
substitutions[i] = [dayInstant];
|
||||||
|
}
|
||||||
|
// Record calls in calls[]
|
||||||
|
TemporalHelpers.observeMethod(calls, timeZone, "getPossibleInstantsFor");
|
||||||
|
return new Temporal.ZonedDateTime(0n, timeZone);
|
||||||
|
}
|
||||||
|
|
||||||
|
let zdt = createRelativeTo(200);
|
||||||
|
calls.splice(0); // Reset calls list after ZonedDateTime construction
|
||||||
|
zdt.since(other, {
|
||||||
|
largestUnit: "day",
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
200 + 1,
|
||||||
|
"Expected ZonedDateTime.since to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
||||||
|
|
||||||
|
zdt = createRelativeTo(300);
|
||||||
|
calls.splice(0); // Reset calls list after previous loop + ZonedDateTime construction
|
||||||
|
zdt.since(other, {
|
||||||
|
largestUnit: "day",
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
300 + 1,
|
||||||
|
"Expected ZonedDateTime.since to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
59
test/built-ins/Temporal/ZonedDateTime/prototype/until/nanoseconds-to-days-loop-indefinitely-1.js
vendored
Normal file
59
test/built-ins/Temporal/ZonedDateTime/prototype/until/nanoseconds-to-days-loop-indefinitely-1.js
vendored
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
// 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.zoneddatetime.prototype.until
|
||||||
|
description: >
|
||||||
|
NanosecondsToDays can loop arbitrarily long, performing observable operations each iteration.
|
||||||
|
info: |
|
||||||
|
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||||
|
|
||||||
|
...
|
||||||
|
15. If sign is 1, then
|
||||||
|
a. Repeat, while days > 0 and intermediateNs > endNs,
|
||||||
|
i. Set days to days - 1.
|
||||||
|
ii. Set intermediateNs to ℝ(? AddZonedDateTime(ℤ(startNs), relativeTo.[[TimeZone]],
|
||||||
|
relativeTo.[[Calendar]], 0, 0, 0, days, 0, 0, 0, 0, 0, 0)).
|
||||||
|
...
|
||||||
|
includes: [temporalHelpers.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const calls = [];
|
||||||
|
const dayLengthNs = 86400000000000n;
|
||||||
|
const other = new Temporal.ZonedDateTime(dayLengthNs, "UTC", "iso8601");
|
||||||
|
|
||||||
|
function createRelativeTo(count) {
|
||||||
|
const tz = new Temporal.TimeZone("UTC");
|
||||||
|
// Record calls in calls[]
|
||||||
|
TemporalHelpers.observeMethod(calls, tz, "getPossibleInstantsFor");
|
||||||
|
const cal = new Temporal.Calendar("iso8601");
|
||||||
|
// Return _count_ days for the second call to dateUntil, behaving normally after
|
||||||
|
TemporalHelpers.substituteMethod(cal, "dateUntil", [
|
||||||
|
TemporalHelpers.SUBSTITUTE_SKIP,
|
||||||
|
Temporal.Duration.from({ days: count }),
|
||||||
|
]);
|
||||||
|
return new Temporal.ZonedDateTime(0n, tz, cal);
|
||||||
|
}
|
||||||
|
|
||||||
|
let zdt = createRelativeTo(200);
|
||||||
|
calls.splice(0); // Reset calls list after ZonedDateTime construction
|
||||||
|
zdt.until(other, {
|
||||||
|
largestUnit: "day",
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
200 + 1,
|
||||||
|
"Expected ZonedDateTime.until to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
||||||
|
|
||||||
|
zdt = createRelativeTo(300);
|
||||||
|
calls.splice(0); // Reset calls list after previous loop + ZonedDateTime construction
|
||||||
|
zdt.until(other, {
|
||||||
|
largestUnit: "day",
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
300 + 1,
|
||||||
|
"Expected ZonedDateTime.until to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
71
test/built-ins/Temporal/ZonedDateTime/prototype/until/nanoseconds-to-days-loop-indefinitely-2.js
vendored
Normal file
71
test/built-ins/Temporal/ZonedDateTime/prototype/until/nanoseconds-to-days-loop-indefinitely-2.js
vendored
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
// 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.zoneddatetime.prototype.until
|
||||||
|
description: >
|
||||||
|
NanosecondsToDays can loop infinitely.
|
||||||
|
info: |
|
||||||
|
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||||
|
|
||||||
|
...
|
||||||
|
18. Repeat, while done is false,
|
||||||
|
a. Let oneDayFartherNs be ℝ(? AddZonedDateTime(ℤ(intermediateNs), relativeTo.[[TimeZone]],
|
||||||
|
relativeTo.[[Calendar]], 0, 0, 0, sign, 0, 0, 0, 0, 0, 0)).
|
||||||
|
b. Set dayLengthNs to oneDayFartherNs - intermediateNs.
|
||||||
|
c. If (nanoseconds - dayLengthNs) × sign ≥ 0, then
|
||||||
|
i. Set nanoseconds to nanoseconds - dayLengthNs.
|
||||||
|
ii. Set intermediateNs to oneDayFartherNs.
|
||||||
|
iii. Set days to days + sign.
|
||||||
|
d. Else,
|
||||||
|
i. Set done to true.
|
||||||
|
includes: [temporalHelpers.js]
|
||||||
|
features: [Temporal]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const calls = [];
|
||||||
|
const dayLengthNs = 86400000000000n;
|
||||||
|
const other = new Temporal.ZonedDateTime(dayLengthNs, "UTC", "iso8601");
|
||||||
|
|
||||||
|
function createRelativeTo(count) {
|
||||||
|
const dayInstant = new Temporal.Instant(dayLengthNs);
|
||||||
|
const substitutions = [];
|
||||||
|
const timeZone = new Temporal.TimeZone("UTC");
|
||||||
|
// Return constant value for first _count_ calls
|
||||||
|
TemporalHelpers.substituteMethod(
|
||||||
|
timeZone,
|
||||||
|
"getPossibleInstantsFor",
|
||||||
|
substitutions
|
||||||
|
);
|
||||||
|
substitutions.length = count;
|
||||||
|
let i = 0;
|
||||||
|
for (i = 0; i < substitutions.length; i++) {
|
||||||
|
// (this value)
|
||||||
|
substitutions[i] = [dayInstant];
|
||||||
|
}
|
||||||
|
// Record calls in calls[]
|
||||||
|
TemporalHelpers.observeMethod(calls, timeZone, "getPossibleInstantsFor");
|
||||||
|
return new Temporal.ZonedDateTime(0n, timeZone);
|
||||||
|
}
|
||||||
|
|
||||||
|
let zdt = createRelativeTo(200);
|
||||||
|
calls.splice(0); // Reset calls list after ZonedDateTime construction
|
||||||
|
zdt.until(other, {
|
||||||
|
largestUnit: "day",
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
200 + 1,
|
||||||
|
"Expected ZonedDateTime.until to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
||||||
|
|
||||||
|
zdt = createRelativeTo(300);
|
||||||
|
calls.splice(0); // Reset calls list after previous loop + ZonedDateTime construction
|
||||||
|
zdt.until(other, {
|
||||||
|
largestUnit: "day",
|
||||||
|
});
|
||||||
|
assert.sameValue(
|
||||||
|
calls.length,
|
||||||
|
300 + 1,
|
||||||
|
"Expected ZonedDateTime.until to call getPossibleInstantsFor correct number of times"
|
||||||
|
);
|
Loading…
Reference in New Issue