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
|
||||
* 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.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.round
|
||||
description: >
|
||||
NanosecondsToDays can loop indefinitely.
|
||||
NanosecondsToDays can loop arbitrarily long, performing observable operations each iteration.
|
||||
info: |
|
||||
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||
|
||||
|
@ -19,54 +18,41 @@ includes: [temporalHelpers.js]
|
|||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Intentionally not Test262Error to ensure assertion errors are correctly propagated.
|
||||
class StopExecution extends Error {}
|
||||
const calls = [];
|
||||
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
|
||||
// is larger than the end date.
|
||||
let twoDays = Temporal.Duration.from({days: 2});
|
||||
|
||||
// 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 = {
|
||||
let zdt = createRelativeTo(200);
|
||||
calls.splice(0); // Reset calls list after ZonedDateTime construction
|
||||
duration.round({
|
||||
largestUnit: "days",
|
||||
relativeTo: zdt,
|
||||
};
|
||||
});
|
||||
assert.sameValue(
|
||||
calls.length,
|
||||
200 + 2,
|
||||
"Expected duration.round to call getPossibleInstantsFor correct number of times"
|
||||
);
|
||||
|
||||
assert.throws(StopExecution, () => duration.round(options));
|
||||
assert.sameValue(count, stopAt);
|
||||
zdt = createRelativeTo(300);
|
||||
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.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
|
||||
/*---
|
||||
esid: sec-temporal.duration.prototype.round
|
||||
description: >
|
||||
NanosecondsToDays can loop indefinitely.
|
||||
NanosecondsToDays can loop infinitely.
|
||||
info: |
|
||||
NanosecondsToDays ( nanoseconds, relativeTo )
|
||||
|
||||
|
@ -23,43 +22,51 @@ includes: [temporalHelpers.js]
|
|||
features: [Temporal]
|
||||
---*/
|
||||
|
||||
// Intentionally not Test262Error to ensure assertion errors are correctly propagated.
|
||||
class StopExecution extends Error {}
|
||||
const calls = [];
|
||||
const duration = Temporal.Duration.from({ days: 1 });
|
||||
|
||||
const stopAt = 1000;
|
||||
|
||||
// Number of calls to getPossibleInstantsFor.
|
||||
let count = 0;
|
||||
|
||||
// UTC time zones so we don't have to worry about time zone offsets.
|
||||
let tz = new class extends Temporal.TimeZone {
|
||||
getPossibleInstantsFor(dt) {
|
||||
// Stop when we've reached the test limit.
|
||||
count += 1;
|
||||
if (count === stopAt) {
|
||||
throw new StopExecution();
|
||||
}
|
||||
|
||||
if (count < 4) {
|
||||
// The first couple calls request the instant for 1970-01-02.
|
||||
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)];
|
||||
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];
|
||||
}
|
||||
}("UTC");
|
||||
// Record calls in calls[]
|
||||
TemporalHelpers.observeMethod(calls, timeZone, "getPossibleInstantsFor");
|
||||
return new Temporal.ZonedDateTime(0n, timeZone);
|
||||
}
|
||||
|
||||
let zdt = new Temporal.ZonedDateTime(0n, tz);
|
||||
let duration = Temporal.Duration.from({days: 1});
|
||||
let options = {
|
||||
let zdt = createRelativeTo(200);
|
||||
calls.splice(0); // Reset calls list after ZonedDateTime construction
|
||||
duration.round({
|
||||
smallestUnit: "days",
|
||||
relativeTo: zdt,
|
||||
};
|
||||
});
|
||||
assert.sameValue(
|
||||
calls.length,
|
||||
200 + 1,
|
||||
"Expected duration.round to call getPossibleInstantsFor correct number of times"
|
||||
);
|
||||
|
||||
assert.throws(StopExecution, () => duration.round(options));
|
||||
assert.sameValue(count, stopAt);
|
||||
zdt = createRelativeTo(300);
|
||||
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