Skip to content

Commit

Permalink
Add tests for Temporal.Duration.p*.with
Browse files Browse the repository at this point in the history
(Philip, March 2022: This was originally Frank's PR #3065. I did some
reformatting, removed duplicate tests, and combined with some existing
tests.)
  • Loading branch information
FrankYFTang authored and rwaldron committed Mar 29, 2022
1 parent f59bafa commit 2c8b69f
Show file tree
Hide file tree
Showing 7 changed files with 368 additions and 9 deletions.
93 changes: 93 additions & 0 deletions test/built-ins/Temporal/Duration/prototype/with/all-negative.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// 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.duration.prototype.with
description: >
Returns a correctly merged object when the argument replaces the fields with
all negative values.
info: |
1. Let duration be the this value.
2. Perform ? RequireInternalSlot(duration, [[InitializedTemporalDuration]]).
3. Let temporalDurationLike be ? ToPartialDuration(temporalDurationLike).
4. If temporalDurationLike.[[Years]] is not undefined, then
a. Let years be temporalDurationLike.[[Years]].
5. Else,
a. Let years be duration.[[Years]].
6. If temporalDurationLike.[[Months]] is not undefined, then
a. Let months be temporalDurationLike.[[Months]].
7. Else,
a. Let months be duration.[[Months]].
8. If temporalDurationLike.[[Weeks]] is not undefined, then
a. Let weeks be temporalDurationLike.[[Weeks]].
9. Else,
a. Let weeks be duration.[[Weeks]].
10. If temporalDurationLike.[[Days]] is not undefined, then
a. Let days be temporalDurationLike.[[Days]].
11. Else,
a. Let days be duration.[[Days]].
12. If temporalDurationLike.[[Hours]] is not undefined, then
a. Let hours be temporalDurationLike.[[Hours]].
13. Else,
a. Let hours be duration.[[Hours]].
14. If temporalDurationLike.[[Minutes]] is not undefined, then
a. Let minutes be temporalDurationLike.[[Minutes]].
15. Else,
a. Let minutes be duration.[[Minutes]].
16. If temporalDurationLike.[[Seconds]] is not undefined, then
a. Let seconds be temporalDurationLike.[[Seconds]].
17. Else,
a. Let seconds be duration.[[Seconds]].
18. If temporalDurationLike.[[Milliseconds]] is not undefined, then
a. Let milliseconds be temporalDurationLike.[[Milliseconds]].
19. Else,
a. Let milliseconds be duration.[[Milliseconds]].
20. If temporalDurationLike.[[Microseconds]] is not undefined, then
a. Let microseconds be temporalDurationLike.[[Microseconds]].
21. Else,
a. Let microseconds be duration.[[Microseconds]].
22. If temporalDurationLike.[[Nanoseconds]] is not undefined, then
a. Let nanoseconds be temporalDurationLike.[[Nanoseconds]].
23. Else,
a. Let nanoseconds be duration.[[Nanoseconds]].
24. Return ? CreateTemporalDuration(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds).
features: [Temporal]
includes: [temporalHelpers.js]
---*/

const argAllNegative = {
years: -9,
months: -8,
weeks: -7,
days: -6,
hours: -5,
minutes: -4,
seconds: -3,
milliseconds: -2,
microseconds: -1,
nanoseconds: -10,
};

const d1 = new Temporal.Duration();
TemporalHelpers.assertDuration(
d1.with(argAllNegative), -9, -8, -7, -6, -5, -4, -3, -2, -1, -10,
"replace all zeroes with all negative"
);

const d2 = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
TemporalHelpers.assertDuration(
d2.with(argAllNegative), -9, -8, -7, -6, -5, -4, -3, -2, -1, -10,
"replace all positive with all negative"
);

const d3 = new Temporal.Duration(1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5, 10e5);
TemporalHelpers.assertDuration(
d3.with(argAllNegative), -9, -8, -7, -6, -5, -4, -3, -2, -1, -10,
"replace all positive large numbers with all negative"
);

const d4 = new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10);
TemporalHelpers.assertDuration(
d4.with(argAllNegative), -9, -8, -7, -6, -5, -4, -3, -2, -1, -10,
"replace all negative with all negative"
);
92 changes: 92 additions & 0 deletions test/built-ins/Temporal/Duration/prototype/with/all-positive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// 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.duration.prototype.with
description: >
Returns a correctly merged object when the argument replaces the fields with
all positive values.
info: |
1. Let duration be the this value.
2. Perform ? RequireInternalSlot(duration, [[InitializedTemporalDuration]]).
3. Let temporalDurationLike be ? ToPartialDuration(temporalDurationLike).
4. If temporalDurationLike.[[Years]] is not undefined, then
a. Let years be temporalDurationLike.[[Years]].
5. Else,
a. Let years be duration.[[Years]].
6. If temporalDurationLike.[[Months]] is not undefined, then
a. Let months be temporalDurationLike.[[Months]].
7. Else,
a. Let months be duration.[[Months]].
8. If temporalDurationLike.[[Weeks]] is not undefined, then
a. Let weeks be temporalDurationLike.[[Weeks]].
9. Else,
a. Let weeks be duration.[[Weeks]].
10. If temporalDurationLike.[[Days]] is not undefined, then
a. Let days be temporalDurationLike.[[Days]].
11. Else,
a. Let days be duration.[[Days]].
12. If temporalDurationLike.[[Hours]] is not undefined, then
a. Let hours be temporalDurationLike.[[Hours]].
13. Else,
a. Let hours be duration.[[Hours]].
14. If temporalDurationLike.[[Minutes]] is not undefined, then
a. Let minutes be temporalDurationLike.[[Minutes]].
15. Else,
a. Let minutes be duration.[[Minutes]].
16. If temporalDurationLike.[[Seconds]] is not undefined, then
a. Let seconds be temporalDurationLike.[[Seconds]].
17. Else,
a. Let seconds be duration.[[Seconds]].
18. If temporalDurationLike.[[Milliseconds]] is not undefined, then
a. Let milliseconds be temporalDurationLike.[[Milliseconds]].
19. Else,
a. Let milliseconds be duration.[[Milliseconds]].
20. If temporalDurationLike.[[Microseconds]] is not undefined, then
a. Let microseconds be temporalDurationLike.[[Microseconds]].
21. Else,
a. Let microseconds be duration.[[Microseconds]].
22. If temporalDurationLike.[[Nanoseconds]] is not undefined, then
a. Let nanoseconds be temporalDurationLike.[[Nanoseconds]].
23. Else,
a. Let nanoseconds be duration.[[Nanoseconds]].
24. Return ? CreateTemporalDuration(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds).
features: [Temporal]
includes: [temporalHelpers.js]
---*/

const argAllPositive = {
years: 9,
months: 8,
weeks: 7,
days: 6,
hours: 5,
minutes: 4,
seconds: 3,
milliseconds: 2,
microseconds: 1,
nanoseconds: 10,
};

const d1 = new Temporal.Duration();
TemporalHelpers.assertDuration(
d1.with(argAllPositive), 9, 8, 7, 6, 5, 4, 3, 2, 1, 10,
"replace all zeroes with all positive"
);

const d2 = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
TemporalHelpers.assertDuration(
d2.with(argAllPositive), 9, 8, 7, 6, 5, 4, 3, 2, 1, 10,
"replace all positive with all positive");

const d3 = new Temporal.Duration(1e5, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, 8e5, 9e5, 10e5);
TemporalHelpers.assertDuration(
d3.with(argAllPositive), 9, 8, 7, 6, 5, 4, 3, 2, 1, 10,
"replace all positive large numbers with all positive"
);

const d4 = new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10);
TemporalHelpers.assertDuration(
d4.with(argAllPositive), 9, 8, 7, 6, 5, 4, 3, 2, 1, 10,
"replace all negative with all positive"
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// 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.duration.prototype.with
description: >
The durationLike argument must contain at least one correctly spelled property
features: [Temporal]
---*/

let d = new Temporal.Duration(1, 2, 3, 4, 5);

[
{},
[],
() => {},
// objects with only singular keys (plural is the correct spelling)
{ year: 1 },
{ month: 2 },
{ week: 3 },
{ day: 4 },
{ hour: 5 },
{ minute: 6 },
{ second: 7 },
{ millisecond: 8 },
{ microsecond: 9 },
{ nanosecond: 10 },
].forEach((badObject) => {
assert.throws(TypeError, () => d.with(badObject),
"Throw TypeError if temporalDurationLike is not valid");
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// 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.duration.prototype.with
description: Throw TypeError if the temporalDurationLike argument is the wrong type
features: [Temporal]
---*/

let d = new Temporal.Duration(1, 2, 3, 4, 5);

[
"string",
"P1YT1M",
true,
false,
NaN,
Infinity,
undefined,
null,
123,
Symbol(),
456n,
].forEach((badInput) => {
assert.throws(TypeError, () => d.with(badInput),
"Throw TypeError if temporalDurationLike is not valid");
});
20 changes: 11 additions & 9 deletions test/built-ins/Temporal/Duration/prototype/with/branding.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ const with_ = Temporal.Duration.prototype.with;

assert.sameValue(typeof with_, "function");

assert.throws(TypeError, () => with_.call(undefined), "undefined");
assert.throws(TypeError, () => with_.call(null), "null");
assert.throws(TypeError, () => with_.call(true), "true");
assert.throws(TypeError, () => with_.call(""), "empty string");
assert.throws(TypeError, () => with_.call(Symbol()), "symbol");
assert.throws(TypeError, () => with_.call(1), "1");
assert.throws(TypeError, () => with_.call({}), "plain object");
assert.throws(TypeError, () => with_.call(Temporal.Duration), "Temporal.Duration");
assert.throws(TypeError, () => with_.call(Temporal.Duration.prototype), "Temporal.Duration.prototype");
const arg = { years: 3 };

assert.throws(TypeError, () => with_.call(undefined, arg), "undefined");
assert.throws(TypeError, () => with_.call(null, arg), "null");
assert.throws(TypeError, () => with_.call(true, arg), "true");
assert.throws(TypeError, () => with_.call("", arg), "empty string");
assert.throws(TypeError, () => with_.call(Symbol(), arg), "symbol");
assert.throws(TypeError, () => with_.call(1, arg), "1");
assert.throws(TypeError, () => with_.call({}, arg), "plain object");
assert.throws(TypeError, () => with_.call(Temporal.Duration, arg), "Temporal.Duration");
assert.throws(TypeError, () => with_.call(Temporal.Duration.prototype, arg), "Temporal.Duration.prototype");
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// 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.duration.prototype.with
description: >
Returns a correctly merged object when the argument replaces only some of the
fields with positive values.
info: |
1. Let duration be the this value.
2. Perform ? RequireInternalSlot(duration, [[InitializedTemporalDuration]]).
3. Let temporalDurationLike be ? ToPartialDuration(temporalDurationLike).
4. If temporalDurationLike.[[Years]] is not undefined, then
a. Let years be temporalDurationLike.[[Years]].
5. Else,
a. Let years be duration.[[Years]].
6. If temporalDurationLike.[[Months]] is not undefined, then
a. Let months be temporalDurationLike.[[Months]].
7. Else,
a. Let months be duration.[[Months]].
8. If temporalDurationLike.[[Weeks]] is not undefined, then
a. Let weeks be temporalDurationLike.[[Weeks]].
9. Else,
a. Let weeks be duration.[[Weeks]].
10. If temporalDurationLike.[[Days]] is not undefined, then
a. Let days be temporalDurationLike.[[Days]].
11. Else,
a. Let days be duration.[[Days]].
12. If temporalDurationLike.[[Hours]] is not undefined, then
a. Let hours be temporalDurationLike.[[Hours]].
13. Else,
a. Let hours be duration.[[Hours]].
14. If temporalDurationLike.[[Minutes]] is not undefined, then
a. Let minutes be temporalDurationLike.[[Minutes]].
15. Else,
a. Let minutes be duration.[[Minutes]].
16. If temporalDurationLike.[[Seconds]] is not undefined, then
a. Let seconds be temporalDurationLike.[[Seconds]].
17. Else,
a. Let seconds be duration.[[Seconds]].
18. If temporalDurationLike.[[Milliseconds]] is not undefined, then
a. Let milliseconds be temporalDurationLike.[[Milliseconds]].
19. Else,
a. Let milliseconds be duration.[[Milliseconds]].
20. If temporalDurationLike.[[Microseconds]] is not undefined, then
a. Let microseconds be temporalDurationLike.[[Microseconds]].
21. Else,
a. Let microseconds be duration.[[Microseconds]].
22. If temporalDurationLike.[[Nanoseconds]] is not undefined, then
a. Let nanoseconds be temporalDurationLike.[[Nanoseconds]].
23. Else,
a. Let nanoseconds be duration.[[Nanoseconds]].
24. Return ? CreateTemporalDuration(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds).
features: [Temporal]
includes: [temporalHelpers.js]
---*/

const durationlike1 = { years: 9, hours: 5 };
const durationlike2 = { months: 8, minutes: 4 };
const durationlike3 = { weeks: 7, seconds: 3 };
const durationlike4 = { days: 6, milliseconds: 2 };
const durationlike5 = { microseconds: 987, nanoseconds: 123 };

const d1 = new Temporal.Duration();
TemporalHelpers.assertDuration(
d1.with(durationlike1), 9, 0, 0, 0, 5, 0, 0, 0, 0, 0, "replace all zeroes with years and hours");
TemporalHelpers.assertDuration(
d1.with(durationlike2), 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, "replace all zeroes wtih months and minutes");
TemporalHelpers.assertDuration(
d1.with(durationlike3), 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, "replace all zeroes with weeks and seconds");
TemporalHelpers.assertDuration(
d1.with(durationlike4), 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, "replace all zeroes with days and milliseconds");
TemporalHelpers.assertDuration(
d1.with(durationlike5), 0, 0, 0, 0, 0, 0, 0, 0, 987, 123, "replace all zeroes with microseconds and nanoseconds");

const d2 = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
TemporalHelpers.assertDuration(
d2.with(durationlike1), 9, 2, 3, 4, 5, 6, 7, 8, 9, 10, "replace all positive with years and hours");
TemporalHelpers.assertDuration(
d2.with(durationlike2), 1, 8, 3, 4, 5, 4, 7, 8, 9, 10, "replace all positive with months and minutes");
TemporalHelpers.assertDuration(
d2.with(durationlike3), 1, 2, 7, 4, 5, 6, 3, 8, 9, 10, "replace all positive with weeks and seconds");
TemporalHelpers.assertDuration(
d2.with(durationlike4), 1, 2, 3, 6, 5, 6, 7, 2, 9, 10, "replace all positive with days and milliseconds");
TemporalHelpers.assertDuration(
d2.with(durationlike5), 1, 2, 3, 4, 5, 6, 7, 8, 987, 123, "replace all positive with microseconds and nanoseconds");
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// 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.duration.prototype.with
description: Throw RangeError if the resulting duration has mixed signs
info: |
24. Return ? CreateTemporalDuration(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds).
features: [Temporal]
---*/

const d1 = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
const d2 = new Temporal.Duration(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10);
const fields = ["years", "months", "weeks", "days", "hours", "minutes", "seconds", "milliseconds", "microseconds", "nanoseconds"];

fields.forEach((field) => {
assert.throws(
RangeError,
() => d1.with({ [field]: -1 }),
`sign in argument { ${field}: -1 } conflicting with sign of duration should throw RangeError`
);

assert.throws(
RangeError,
() => d2.with({ [field]: 1 }),
`sign in argument { ${field}: 1 } conflicting with sign of duration should throw RangeError`
);
});

0 comments on commit 2c8b69f

Please sign in to comment.