From 3d5c52e112c9a40d94e1bfa89158f5ee25f787ff Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Wed, 3 Jul 2024 08:56:34 -0700 Subject: [PATCH] add tests for Math.sumPrecise (#4049) * add tests for Math.sumPrecise * add feature * I hate yaml * fix writability check --- features.txt | 4 + test/built-ins/Math/sumPrecise/length.js | 16 ++++ test/built-ins/Math/sumPrecise/name.js | 16 ++++ .../Math/sumPrecise/not-a-constructor.js | 15 ++++ test/built-ins/Math/sumPrecise/prop-desc.js | 14 ++++ test/built-ins/Math/sumPrecise/sum-is-NaN.js | 12 +++ .../Math/sumPrecise/sum-is-infinite.js | 13 ++++ .../Math/sumPrecise/sum-is-minus-zero.js | 13 ++++ test/built-ins/Math/sumPrecise/sum.js | 37 ++++++++++ .../Math/sumPrecise/takes-iterable.js | 32 ++++++++ .../Math/sumPrecise/throws-on-non-number.js | 74 +++++++++++++++++++ 11 files changed, 246 insertions(+) create mode 100644 test/built-ins/Math/sumPrecise/length.js create mode 100644 test/built-ins/Math/sumPrecise/name.js create mode 100644 test/built-ins/Math/sumPrecise/not-a-constructor.js create mode 100644 test/built-ins/Math/sumPrecise/prop-desc.js create mode 100644 test/built-ins/Math/sumPrecise/sum-is-NaN.js create mode 100644 test/built-ins/Math/sumPrecise/sum-is-infinite.js create mode 100644 test/built-ins/Math/sumPrecise/sum-is-minus-zero.js create mode 100644 test/built-ins/Math/sumPrecise/sum.js create mode 100644 test/built-ins/Math/sumPrecise/takes-iterable.js create mode 100644 test/built-ins/Math/sumPrecise/throws-on-non-number.js diff --git a/features.txt b/features.txt index 4934929d05..1a43df40dd 100644 --- a/features.txt +++ b/features.txt @@ -121,6 +121,10 @@ explicit-resource-management # https://github.com/tc39/proposal-float16array Float16Array +# Math.sumPrecise +# https://github.com/tc39/proposal-math-sum +Math.sumPrecise + # Source Phase Imports ## https://github.com/tc39/proposal-source-phase-imports source-phase-imports diff --git a/test/built-ins/Math/sumPrecise/length.js b/test/built-ins/Math/sumPrecise/length.js new file mode 100644 index 0000000000..43d0bb7bc6 --- /dev/null +++ b/test/built-ins/Math/sumPrecise/length.js @@ -0,0 +1,16 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-math.sumprecise +description: Math.sumPrecise.length is 1. +includes: [propertyHelper.js] +features: [Math.sumPrecise] +---*/ + +verifyProperty(Math.sumPrecise, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/Math/sumPrecise/name.js b/test/built-ins/Math/sumPrecise/name.js new file mode 100644 index 0000000000..f6c988e578 --- /dev/null +++ b/test/built-ins/Math/sumPrecise/name.js @@ -0,0 +1,16 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-math.sumprecise +description: Math.sumPrecise.name is "sumPrecise". +includes: [propertyHelper.js] +features: [Math.sumPrecise] +---*/ + +verifyProperty(Math.sumPrecise, "name", { + value: "sumPrecise", + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/Math/sumPrecise/not-a-constructor.js b/test/built-ins/Math/sumPrecise/not-a-constructor.js new file mode 100644 index 0000000000..a0b2aa4049 --- /dev/null +++ b/test/built-ins/Math/sumPrecise/not-a-constructor.js @@ -0,0 +1,15 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-math.sumprecise +description: Math.sumPrecise does not implement [[Construct]], is not new-able +includes: [isConstructor.js] +features: [Reflect.construct, Math.sumPrecise] +---*/ + +assert.sameValue(isConstructor(Math.sumPrecise), false, "isConstructor(Math.sumPrecise) must return false"); + +assert.throws(TypeError, function () { + new Math.sumPrecise(); +}); diff --git a/test/built-ins/Math/sumPrecise/prop-desc.js b/test/built-ins/Math/sumPrecise/prop-desc.js new file mode 100644 index 0000000000..f91a8c8cc9 --- /dev/null +++ b/test/built-ins/Math/sumPrecise/prop-desc.js @@ -0,0 +1,14 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-math.sumprecise +description: checks the "sumPrecise" property of Math +includes: [propertyHelper.js] +features: [Math.sumPrecise] +---*/ + +verifyProperty(Math, "sumPrecise", { + writable: true, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/Math/sumPrecise/sum-is-NaN.js b/test/built-ins/Math/sumPrecise/sum-is-NaN.js new file mode 100644 index 0000000000..469f89ca1c --- /dev/null +++ b/test/built-ins/Math/sumPrecise/sum-is-NaN.js @@ -0,0 +1,12 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-math.sumprecise +description: Math.sumPrecise returns NaN when input has NaN or when adding infinities +features: [Math.sumPrecise] +---*/ + +assert.sameValue(Math.sumPrecise([NaN]), NaN); +assert.sameValue(Math.sumPrecise([Infinity, -Infinity]), NaN); +assert.sameValue(Math.sumPrecise([-Infinity, Infinity]), NaN); diff --git a/test/built-ins/Math/sumPrecise/sum-is-infinite.js b/test/built-ins/Math/sumPrecise/sum-is-infinite.js new file mode 100644 index 0000000000..9844688a96 --- /dev/null +++ b/test/built-ins/Math/sumPrecise/sum-is-infinite.js @@ -0,0 +1,13 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-math.sumprecise +description: Math.sumPrecise sums infinities +features: [Math.sumPrecise] +---*/ + +assert.sameValue(Math.sumPrecise([Infinity]), Infinity); +assert.sameValue(Math.sumPrecise([Infinity, Infinity]), Infinity); +assert.sameValue(Math.sumPrecise([-Infinity]), -Infinity); +assert.sameValue(Math.sumPrecise([-Infinity, -Infinity]), -Infinity); diff --git a/test/built-ins/Math/sumPrecise/sum-is-minus-zero.js b/test/built-ins/Math/sumPrecise/sum-is-minus-zero.js new file mode 100644 index 0000000000..5dc9029766 --- /dev/null +++ b/test/built-ins/Math/sumPrecise/sum-is-minus-zero.js @@ -0,0 +1,13 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-math.sumprecise +description: Math.sumPrecise returns -0 on an empty list or list of all -0 +features: [Math.sumPrecise] +---*/ + +assert.sameValue(Math.sumPrecise([]), -0); +assert.sameValue(Math.sumPrecise([-0]), -0); +assert.sameValue(Math.sumPrecise([-0, -0]), -0); +assert.sameValue(Math.sumPrecise([-0, 0]), 0); diff --git a/test/built-ins/Math/sumPrecise/sum.js b/test/built-ins/Math/sumPrecise/sum.js new file mode 100644 index 0000000000..1c1141e0f7 --- /dev/null +++ b/test/built-ins/Math/sumPrecise/sum.js @@ -0,0 +1,37 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-math.sumprecise +description: Math.sumPrecise performs maximally precise summation of finite values +features: [Math.sumPrecise] +---*/ + +assert.sameValue(Math.sumPrecise([1, 2, 3]), 6); +assert.sameValue(Math.sumPrecise([1e308]), 1e308); +assert.sameValue(Math.sumPrecise([1e308, -1e308]), 0); +assert.sameValue(Math.sumPrecise([0.1]), 0.1); +assert.sameValue(Math.sumPrecise([0.1, 0.1]), 0.2); +assert.sameValue(Math.sumPrecise([0.1, -0.1]), 0); +assert.sameValue(Math.sumPrecise([1e308, 1e308, 0.1, 0.1, 1e30, 0.1, -1e30, -1e308, -1e308]), 0.30000000000000004); +assert.sameValue(Math.sumPrecise([1e30, 0.1, -1e30]), 0.1); + +// These cases are chosen for having exercised bugs in real implementations. +// There is no other logic behind choice of constants. +assert.sameValue(Math.sumPrecise([8.98846567431158e+307, 8.988465674311579e+307, -1.7976931348623157e+308]), 9.9792015476736e+291); +assert.sameValue(Math.sumPrecise([-5.630637621603525e+255, 9.565271205476345e+307, 2.9937604643020797e+292]), 9.565271205476347e+307); +assert.sameValue(Math.sumPrecise([6.739986666787661e+66, 2, -1.2689709186578243e-116, 1.7046015739467354e+308, -9.979201547673601e+291, 6.160926733208294e+307, -3.179557053031852e+234, -7.027282978772846e+307, -0.7500000000000001]), 1.61796594939028e+308); +assert.sameValue(Math.sumPrecise([0.31150493246968836, -8.988465674311582e+307, 1.8315037361673755e-270, -15.999999999999996, 2.9999999999999996, 7.345200721499384e+164, -2.033582473639399, -8.98846567431158e+307, -3.5737295155405993e+292, 4.13894772383715e-124, -3.6111186457260667e-35, 2.387234887098013e+180, 7.645295562778372e-298, 3.395189016861822e-103, -2.6331611115768973e-149]), -Infinity); +assert.sameValue(Math.sumPrecise([-1.1442589134409902e+308, 9.593842098384855e+138, 4.494232837155791e+307, -1.3482698511467367e+308, 4.494232837155792e+307]), -1.5936821971565685e+308); +assert.sameValue(Math.sumPrecise([-1.1442589134409902e+308, 4.494232837155791e+307, -1.3482698511467367e+308, 4.494232837155792e+307]), -1.5936821971565687e+308); +assert.sameValue(Math.sumPrecise([9.593842098384855e+138, -6.948356297254111e+307, -1.3482698511467367e+308, 4.494232837155792e+307]), -1.5936821971565685e+308); +assert.sameValue(Math.sumPrecise([-2.534858246857893e+115, 8.988465674311579e+307, 8.98846567431158e+307]), 1.7976931348623157e+308); +assert.sameValue(Math.sumPrecise([1.3588124894186193e+308, 1.4803986201152006e+223, 6.741349255733684e+307]), Infinity); +assert.sameValue(Math.sumPrecise([6.741349255733684e+307, 1.7976931348623155e+308, -7.388327292663961e+41]), Infinity); +assert.sameValue(Math.sumPrecise([-1.9807040628566093e+28, 1.7976931348623157e+308, 9.9792015476736e+291]), 1.7976931348623157e+308); +assert.sameValue(Math.sumPrecise([-1.0214557991173964e+61, 1.7976931348623157e+308, 8.98846567431158e+307, -8.988465674311579e+307]), 1.7976931348623157e+308); +assert.sameValue(Math.sumPrecise([1.7976931348623157e+308, 7.999999999999999, -1.908963895403937e-230, 1.6445950082320264e+292, 2.0734856707605806e+205]), Infinity); +assert.sameValue(Math.sumPrecise([6.197409167220438e-223, -9.979201547673601e+291, -1.7976931348623157e+308]), -Infinity); +assert.sameValue(Math.sumPrecise([4.49423283715579e+307, 8.944251746776101e+307, -0.0002441406250000001, 1.1752060710043817e+308, 4.940846717201632e+292, -1.6836699406454528e+308]), 8.353845887521184e+307); +assert.sameValue(Math.sumPrecise([8.988465674311579e+307, 7.999999999999998, 7.029158107234023e-308, -2.2303483759420562e-172, -1.7976931348623157e+308, -8.98846567431158e+307]), -1.7976931348623157e+308); +assert.sameValue(Math.sumPrecise([8.98846567431158e+307, 8.98846567431158e+307]), Infinity); diff --git a/test/built-ins/Math/sumPrecise/takes-iterable.js b/test/built-ins/Math/sumPrecise/takes-iterable.js new file mode 100644 index 0000000000..b339709986 --- /dev/null +++ b/test/built-ins/Math/sumPrecise/takes-iterable.js @@ -0,0 +1,32 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-math.sumprecise +description: Math.sumPrecise takes an iterable +features: [generators, Math.sumPrecise] +---*/ + +assert.sameValue(Math.sumPrecise([1, 2]), 3); + +function* gen() { + yield 1; + yield 2; +} +assert.sameValue(Math.sumPrecise(gen()), 3); + +var overridenArray = [4]; +overridenArray[Symbol.iterator] = gen; +assert.sameValue(Math.sumPrecise(overridenArray), 3); + +assert.throws(TypeError, function () { + Math.sumPrecise(); +}); + +assert.throws(TypeError, function () { + Math.sumPrecise(1, 2); +}); + +assert.throws(TypeError, function () { + Math.sumPrecise({}); +}); diff --git a/test/built-ins/Math/sumPrecise/throws-on-non-number.js b/test/built-ins/Math/sumPrecise/throws-on-non-number.js new file mode 100644 index 0000000000..2d992f9346 --- /dev/null +++ b/test/built-ins/Math/sumPrecise/throws-on-non-number.js @@ -0,0 +1,74 @@ +// Copyright (C) 2024 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-math.sumprecise +description: Math.sumPrecise throws and closes the iterator if any element is not a Number +features: [Math.sumPrecise] +---*/ + +assert.throws(TypeError, function () { + Math.sumPrecise([{}]); +}); + +assert.throws(TypeError, function () { + Math.sumPrecise([0n]); +}); + + +var coercions = 0; +var objectWithValueOf = { + valueOf: function() { + ++coercions; + throw new Test262Error("valueOf should not be called"); + }, + toString: function() { + ++coercions; + throw new Test262Error("toString should not be called"); + } +}; + +assert.throws(TypeError, function () { + Math.sumPrecise([objectWithValueOf]); +}); +assert.sameValue(coercions, 0); + +assert.throws(TypeError, function () { + Math.sumPrecise([objectWithValueOf, NaN]); +}); +assert.sameValue(coercions, 0); + +assert.throws(TypeError, function () { + Math.sumPrecise([NaN, objectWithValueOf]); +}); +assert.sameValue(coercions, 0); + +assert.throws(TypeError, function () { + Math.sumPrecise([-Infinity, Infinity, objectWithValueOf]); +}); +assert.sameValue(coercions, 0); + +var nextCalls = 0; +var closed = false; +var iterator = { + next: function () { + ++nextCalls; + return { done: false, value: objectWithValueOf }; + }, + return: function () { + closed = true; + return {}; + } +}; +var iterable = { + [Symbol.iterator]: function () { + return iterator; + } +}; + +assert.throws(TypeError, function () { + Math.sumPrecise(iterable); +}); +assert.sameValue(coercions, 0); +assert.sameValue(nextCalls, 1); +assert.sameValue(closed, true);