github.com/pygolin/runtime@v0.0.0-20201208210830-a62e3cd39798/complex_test.go (about) 1 // Copyright 2016 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package runtime 16 17 import ( 18 "errors" 19 "math" 20 "math/big" 21 "math/cmplx" 22 "testing" 23 ) 24 25 func TestComplexAbs(t *testing.T) { 26 cases := []invokeTestCase{ 27 {args: wrapArgs(complex(0, 0)), want: NewFloat(0).ToObject()}, 28 {args: wrapArgs(complex(1, 1)), want: NewFloat(1.4142135623730951).ToObject()}, 29 {args: wrapArgs(complex(1, 2)), want: NewFloat(2.23606797749979).ToObject()}, 30 {args: wrapArgs(complex(3, 4)), want: NewFloat(5).ToObject()}, 31 {args: wrapArgs(complex(-3, 4)), want: NewFloat(5).ToObject()}, 32 {args: wrapArgs(complex(3, -4)), want: NewFloat(5).ToObject()}, 33 {args: wrapArgs(-complex(3, 4)), want: NewFloat(5).ToObject()}, 34 {args: wrapArgs(complex(0.123456e-3, 0)), want: NewFloat(0.000123456).ToObject()}, 35 {args: wrapArgs(complex(0.123456e-3, 3.14151692e+7)), want: NewFloat(31415169.2).ToObject()}, 36 {args: wrapArgs(complex(math.Inf(-1), 1.2)), want: NewFloat(math.Inf(1)).ToObject()}, 37 {args: wrapArgs(complex(3.4, math.Inf(1))), want: NewFloat(math.Inf(1)).ToObject()}, 38 {args: wrapArgs(complex(math.Inf(1), math.Inf(-1))), want: NewFloat(math.Inf(1)).ToObject()}, 39 {args: wrapArgs(complex(math.Inf(1), math.NaN())), want: NewFloat(math.Inf(1)).ToObject()}, 40 {args: wrapArgs(complex(math.NaN(), math.Inf(1))), want: NewFloat(math.Inf(1)).ToObject()}, 41 {args: wrapArgs(complex(math.NaN(), 5.6)), want: NewFloat(math.NaN()).ToObject()}, 42 {args: wrapArgs(complex(7.8, math.NaN())), want: NewFloat(math.NaN()).ToObject()}, 43 } 44 for _, cas := range cases { 45 switch got, match := checkInvokeResult(wrapFuncForTest(complexAbs), cas.args, cas.want, cas.wantExc); match { 46 case checkInvokeResultReturnValueMismatch: 47 if got == nil || cas.want == nil || !got.isInstance(FloatType) || !cas.want.isInstance(FloatType) || 48 !floatsAreSame(toFloatUnsafe(got).Value(), toFloatUnsafe(cas.want).Value()) { 49 t.Errorf("complex.__abs__%v = %v, want %v", cas.args, got, cas.want) 50 } 51 } 52 } 53 } 54 55 func TestComplexEq(t *testing.T) { 56 cases := []invokeTestCase{ 57 {args: wrapArgs(complex(0, 0), 0), want: True.ToObject()}, 58 {args: wrapArgs(complex(1, 0), 0), want: False.ToObject()}, 59 {args: wrapArgs(complex(-12, 0), -12), want: True.ToObject()}, 60 {args: wrapArgs(complex(-12, 0), 1), want: False.ToObject()}, 61 {args: wrapArgs(complex(17.20, 0), 17.20), want: True.ToObject()}, 62 {args: wrapArgs(complex(1.2, 0), 17.20), want: False.ToObject()}, 63 {args: wrapArgs(complex(-4, 15), complex(-4, 15)), want: True.ToObject()}, 64 {args: wrapArgs(complex(-4, 15), complex(1, 2)), want: False.ToObject()}, 65 {args: wrapArgs(complex(math.Inf(1), 0), complex(math.Inf(1), 0)), want: True.ToObject()}, 66 {args: wrapArgs(complex(math.Inf(1), 0), complex(0, math.Inf(1))), want: False.ToObject()}, 67 {args: wrapArgs(complex(math.Inf(-1), 0), complex(math.Inf(-1), 0)), want: True.ToObject()}, 68 {args: wrapArgs(complex(math.Inf(-1), 0), complex(0, math.Inf(-1))), want: False.ToObject()}, 69 {args: wrapArgs(complex(math.Inf(1), math.Inf(1)), complex(math.Inf(1), math.Inf(1))), want: True.ToObject()}, 70 } 71 for _, cas := range cases { 72 if err := runInvokeTestCase(wrapFuncForTest(complexEq), &cas); err != "" { 73 t.Error(err) 74 } 75 } 76 } 77 78 // FIXME(corona10): Since Go 1.9 moved to C99 float division and what CPython uses as well. 79 // Some tests can be failed with version < Go 1.9. We need to detect Go version. 80 // And changed expected values. 81 82 func TestComplexBinaryOps(t *testing.T) { 83 cases := []struct { 84 fun func(f *Frame, v, w *Object) (*Object, *BaseException) 85 v, w *Object 86 want *Object 87 wantExc *BaseException 88 }{ 89 {Add, NewComplex(1 + 3i).ToObject(), NewInt(1).ToObject(), NewComplex(2 + 3i).ToObject(), nil}, 90 {Add, NewComplex(1 + 3i).ToObject(), NewFloat(-1).ToObject(), NewComplex(3i).ToObject(), nil}, 91 {Add, NewComplex(1 + 3i).ToObject(), NewInt(1).ToObject(), NewComplex(2 + 3i).ToObject(), nil}, 92 {Add, NewComplex(1 + 3i).ToObject(), NewComplex(-1 - 3i).ToObject(), NewComplex(0i).ToObject(), nil}, 93 {Add, NewFloat(math.Inf(1)).ToObject(), NewComplex(3i).ToObject(), NewComplex(complex(math.Inf(1), 3)).ToObject(), nil}, 94 {Add, NewFloat(math.Inf(-1)).ToObject(), NewComplex(3i).ToObject(), NewComplex(complex(math.Inf(-1), 3)).ToObject(), nil}, 95 {Add, NewFloat(math.NaN()).ToObject(), NewComplex(3i).ToObject(), NewComplex(complex(math.NaN(), 3)).ToObject(), nil}, 96 {Add, NewComplex(cmplx.NaN()).ToObject(), NewComplex(3i).ToObject(), NewComplex(cmplx.NaN()).ToObject(), nil}, 97 {Add, NewFloat(math.Inf(-1)).ToObject(), NewComplex(complex(math.Inf(+1), 3)).ToObject(), NewComplex(complex(math.NaN(), 3)).ToObject(), nil}, 98 {Add, NewComplex(1 + 3i).ToObject(), None, nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for +: 'complex' and 'NoneType'")}, 99 {Add, None, NewComplex(1 + 3i).ToObject(), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for +: 'NoneType' and 'complex'")}, 100 {Add, NewInt(3).ToObject(), NewComplex(3i).ToObject(), NewComplex(3 + 3i).ToObject(), nil}, 101 {Add, NewLong(big.NewInt(9999999)).ToObject(), NewComplex(3i).ToObject(), NewComplex(9999999 + 3i).ToObject(), nil}, 102 {Add, NewFloat(3.5).ToObject(), NewComplex(3i).ToObject(), NewComplex(3.5 + 3i).ToObject(), nil}, 103 {Div, NewComplex(1 + 2i).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(1 + 0i).ToObject(), nil}, 104 {Div, NewComplex(3 + 4i).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(2.2 - 0.4i).ToObject(), nil}, 105 {Div, NewComplex(3.14 - 0.618i).ToObject(), NewComplex(-0.123e-4 + 0.151692i).ToObject(), NewComplex(-4.075723201992163 - 20.69950866627519i).ToObject(), nil}, 106 {Div, NewInt(3).ToObject(), NewComplex(3 - 4i).ToObject(), NewComplex(0.36 + 0.48i).ToObject(), nil}, 107 {Div, NewComplex(3 + 4i).ToObject(), NewInt(-5).ToObject(), NewComplex(-0.6 - 0.8i).ToObject(), nil}, 108 {Div, NewFloat(1.2).ToObject(), NewComplex(1 - 2i).ToObject(), NewComplex(0.24 + 0.48i).ToObject(), nil}, 109 {Div, NewComplex(1 + 2i).ToObject(), NewFloat(-3.4).ToObject(), NewComplex(-0.29411764705882354 - 0.5882352941176471i).ToObject(), nil}, 110 {Div, NewLong(big.NewInt(123)).ToObject(), NewComplex(3 + 4i).ToObject(), NewComplex(14.76 - 19.68i).ToObject(), nil}, 111 {Div, NewComplex(3 - 4i).ToObject(), NewLong(big.NewInt(-34)).ToObject(), NewComplex(-0.08823529411764706 + 0.11764705882352941i).ToObject(), nil}, 112 {Div, NewComplex(3 + 4i).ToObject(), NewComplex(complex(math.Inf(1), math.Inf(-1))).ToObject(), NewComplex(0i).ToObject(), nil}, 113 {Div, NewComplex(3 + 4i).ToObject(), NewComplex(complex(math.Inf(1), 2)).ToObject(), NewComplex(0i).ToObject(), nil}, 114 {Div, NewComplex(complex(math.Inf(1), math.Inf(1))).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(complex(math.Inf(1), math.NaN())).ToObject(), nil}, 115 {Div, NewComplex(complex(math.Inf(1), 4)).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(complex(math.Inf(1), math.Inf(-1))).ToObject(), nil}, 116 {Div, NewComplex(complex(3, math.Inf(1))).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(complex(math.Inf(1), math.Inf(1))).ToObject(), nil}, 117 {Div, NewComplex(complex(3, math.NaN())).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(complex(math.NaN(), math.NaN())).ToObject(), nil}, 118 {Div, NewStr("foo").ToObject(), NewComplex(1 + 2i).ToObject(), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for /: 'str' and 'complex'")}, 119 {Div, NewComplex(3 + 4i).ToObject(), NewComplex(0 + 0i).ToObject(), nil, mustCreateException(ZeroDivisionErrorType, "complex division or modulo by zero")}, 120 {Div, NewComplex(complex(math.Inf(1), math.NaN())).ToObject(), NewComplex(0 + 0i).ToObject(), nil, mustCreateException(ZeroDivisionErrorType, "complex division or modulo by zero")}, 121 {Div, NewComplex(3 + 4i).ToObject(), NewLong(bigLongNumber).ToObject(), nil, mustCreateException(OverflowErrorType, "long int too large to convert to complex")}, 122 {FloorDiv, NewComplex(1 + 2i).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(1 + 0i).ToObject(), nil}, 123 {FloorDiv, NewComplex(3 + 4i).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(2 - 0i).ToObject(), nil}, 124 {FloorDiv, NewComplex(3.14 - 0.618i).ToObject(), NewComplex(-0.123e-4 + 0.151692i).ToObject(), NewComplex(-5 - 0i).ToObject(), nil}, 125 {FloorDiv, NewInt(3).ToObject(), NewComplex(3 - 4i).ToObject(), NewComplex(0i).ToObject(), nil}, 126 {FloorDiv, NewComplex(3 + 4i).ToObject(), NewInt(-5).ToObject(), NewComplex(-1 + 0i).ToObject(), nil}, 127 {FloorDiv, NewFloat(1.2).ToObject(), NewComplex(1 - 2i).ToObject(), NewComplex(0i).ToObject(), nil}, 128 {FloorDiv, NewComplex(1 + 2i).ToObject(), NewFloat(-3.4).ToObject(), NewComplex(-1 + 0i).ToObject(), nil}, 129 {FloorDiv, NewLong(big.NewInt(123)).ToObject(), NewComplex(3 + 4i).ToObject(), NewComplex(14 - 0i).ToObject(), nil}, 130 {FloorDiv, NewComplex(3 - 4i).ToObject(), NewLong(big.NewInt(-34)).ToObject(), NewComplex(-1 + 0i).ToObject(), nil}, 131 {FloorDiv, NewComplex(3 + 4i).ToObject(), NewComplex(complex(math.Inf(1), math.Inf(-1))).ToObject(), NewComplex(0i).ToObject(), nil}, 132 {FloorDiv, NewComplex(3 + 4i).ToObject(), NewComplex(complex(math.Inf(1), 2)).ToObject(), NewComplex(0i).ToObject(), nil}, 133 {FloorDiv, NewComplex(complex(math.Inf(1), math.Inf(1))).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(complex(math.Inf(1), 0)).ToObject(), nil}, 134 {FloorDiv, NewComplex(complex(math.Inf(1), 4)).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(complex(math.Inf(1), 0)).ToObject(), nil}, 135 {FloorDiv, NewComplex(complex(3, math.Inf(1))).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(complex(math.Inf(1), 0)).ToObject(), nil}, 136 {FloorDiv, NewComplex(complex(3, math.NaN())).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(complex(math.NaN(), 0)).ToObject(), nil}, 137 {FloorDiv, NewStr("foo").ToObject(), NewComplex(1 + 2i).ToObject(), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for //: 'str' and 'complex'")}, 138 {FloorDiv, NewComplex(3 + 4i).ToObject(), NewComplex(0 + 0i).ToObject(), nil, mustCreateException(ZeroDivisionErrorType, "complex division or modulo by zero")}, 139 {FloorDiv, NewComplex(complex(math.Inf(1), math.NaN())).ToObject(), NewComplex(0 + 0i).ToObject(), nil, mustCreateException(ZeroDivisionErrorType, "complex division or modulo by zero")}, 140 {FloorDiv, NewComplex(3 + 4i).ToObject(), NewLong(bigLongNumber).ToObject(), nil, mustCreateException(OverflowErrorType, "long int too large to convert to complex")}, 141 {Mod, NewComplex(3 + 4i).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(1 + 0i).ToObject(), nil}, 142 {Mod, NewComplex(1 + 2i).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(0i).ToObject(), nil}, 143 {Mod, NewComplex(3.14 - 0.618i).ToObject(), NewComplex(-0.123e-4 + 0.151692i).ToObject(), NewComplex(3.1399385 + 0.14045999999999992i).ToObject(), nil}, 144 {Mod, NewInt(3).ToObject(), NewComplex(3 - 4i).ToObject(), NewComplex(3 + 0i).ToObject(), nil}, 145 {Mod, NewComplex(3 + 4i).ToObject(), NewInt(-5).ToObject(), NewComplex(-2 + 4i).ToObject(), nil}, 146 {Mod, NewFloat(1.2).ToObject(), NewComplex(1 - 2i).ToObject(), NewComplex(1.2 + 0i).ToObject(), nil}, 147 {Mod, NewComplex(1 + 2i).ToObject(), NewFloat(-3.4).ToObject(), NewComplex(-2.4 + 2i).ToObject(), nil}, 148 {Mod, NewLong(big.NewInt(123)).ToObject(), NewComplex(3 + 4i).ToObject(), NewComplex(81 - 56i).ToObject(), nil}, 149 {Mod, NewComplex(3 - 4i).ToObject(), NewLong(big.NewInt(-34)).ToObject(), NewComplex(-31 - 4i).ToObject(), nil}, 150 {Mod, NewComplex(3 + 4i).ToObject(), NewComplex(complex(math.Inf(1), math.Inf(-1))).ToObject(), NewComplex(complex(math.NaN(), math.NaN())).ToObject(), nil}, 151 {Mod, NewComplex(3 + 4i).ToObject(), NewComplex(complex(math.Inf(1), 2)).ToObject(), NewComplex(complex(math.NaN(), math.NaN())).ToObject(), nil}, 152 {Mod, NewComplex(complex(math.Inf(1), math.Inf(1))).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(complex(math.NaN(), math.NaN())).ToObject(), nil}, 153 {Mod, NewComplex(complex(math.Inf(1), 4)).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(complex(math.NaN(), math.Inf(-1))).ToObject(), nil}, 154 {Mod, NewComplex(complex(3, math.Inf(1))).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(complex(math.Inf(-1), math.NaN())).ToObject(), nil}, 155 {Mod, NewComplex(complex(3, math.NaN())).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(complex(math.NaN(), math.NaN())).ToObject(), nil}, 156 {Mod, NewStr("foo").ToObject(), NewComplex(1 + 2i).ToObject(), nil, mustCreateException(TypeErrorType, "not all arguments converted during string formatting")}, 157 {Mod, NewComplex(3 + 4i).ToObject(), NewComplex(0 + 0i).ToObject(), nil, mustCreateException(ZeroDivisionErrorType, "complex division or modulo by zero")}, 158 {Mod, NewComplex(complex(math.Inf(1), math.NaN())).ToObject(), NewComplex(0 + 0i).ToObject(), nil, mustCreateException(ZeroDivisionErrorType, "complex division or modulo by zero")}, 159 {Mod, NewComplex(3 + 4i).ToObject(), NewLong(bigLongNumber).ToObject(), nil, mustCreateException(OverflowErrorType, "long int too large to convert to complex")}, 160 {Sub, NewComplex(1 + 3i).ToObject(), NewComplex(1 + 3i).ToObject(), NewComplex(0i).ToObject(), nil}, 161 {Sub, NewComplex(1 + 3i).ToObject(), NewComplex(3i).ToObject(), NewComplex(1).ToObject(), nil}, 162 {Sub, NewComplex(1 + 3i).ToObject(), NewFloat(1).ToObject(), NewComplex(3i).ToObject(), nil}, 163 {Sub, NewComplex(3i).ToObject(), NewFloat(1.2).ToObject(), NewComplex(-1.2 + 3i).ToObject(), nil}, 164 {Sub, NewComplex(1 + 3i).ToObject(), NewComplex(1 + 3i).ToObject(), NewComplex(0i).ToObject(), nil}, 165 {Sub, NewComplex(4 + 3i).ToObject(), NewInt(1).ToObject(), NewComplex(3 + 3i).ToObject(), nil}, 166 {Sub, NewComplex(4 + 3i).ToObject(), NewLong(big.NewInt(99994)).ToObject(), NewComplex(-99990 + 3i).ToObject(), nil}, 167 {Sub, NewFloat(math.Inf(1)).ToObject(), NewComplex(3i).ToObject(), NewComplex(complex(math.Inf(1), -3)).ToObject(), nil}, 168 {Sub, NewFloat(math.Inf(-1)).ToObject(), NewComplex(3i).ToObject(), NewComplex(complex(math.Inf(-1), -3)).ToObject(), nil}, 169 {Sub, NewComplex(1 + 3i).ToObject(), None, nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for -: 'complex' and 'NoneType'")}, 170 {Sub, None, NewComplex(1 + 3i).ToObject(), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for -: 'NoneType' and 'complex'")}, 171 {Sub, NewFloat(math.NaN()).ToObject(), NewComplex(3i).ToObject(), NewComplex(complex(math.NaN(), -3)).ToObject(), nil}, 172 {Sub, NewComplex(cmplx.NaN()).ToObject(), NewComplex(3i).ToObject(), NewComplex(cmplx.NaN()).ToObject(), nil}, 173 {Sub, NewFloat(math.Inf(-1)).ToObject(), NewComplex(complex(math.Inf(-1), 3)).ToObject(), NewComplex(complex(math.NaN(), -3)).ToObject(), nil}, 174 {Mul, NewComplex(1 + 3i).ToObject(), NewComplex(1 + 3i).ToObject(), NewComplex(-8 + 6i).ToObject(), nil}, 175 {Mul, NewComplex(1 + 3i).ToObject(), NewComplex(3i).ToObject(), NewComplex(-9 + 3i).ToObject(), nil}, 176 {Mul, NewComplex(1 + 3i).ToObject(), NewFloat(1).ToObject(), NewComplex(1 + 3i).ToObject(), nil}, 177 {Mul, NewComplex(3i).ToObject(), NewFloat(1.2).ToObject(), NewComplex(3.5999999999999996i).ToObject(), nil}, 178 {Mul, NewComplex(1 + 3i).ToObject(), NewComplex(1 + 3i).ToObject(), NewComplex(-8 + 6i).ToObject(), nil}, 179 {Mul, NewComplex(4 + 3i).ToObject(), NewInt(1).ToObject(), NewComplex(4 + 3i).ToObject(), nil}, 180 {Mul, NewComplex(4 + 3i).ToObject(), NewLong(big.NewInt(99994)).ToObject(), NewComplex(399976 + 299982i).ToObject(), nil}, 181 {Mul, NewFloat(math.Inf(1)).ToObject(), NewComplex(3i).ToObject(), NewComplex(complex(math.NaN(), math.Inf(1))).ToObject(), nil}, 182 {Mul, NewFloat(math.Inf(-1)).ToObject(), NewComplex(3i).ToObject(), NewComplex(complex(math.NaN(), math.Inf(-1))).ToObject(), nil}, 183 {Mul, NewComplex(1 + 3i).ToObject(), None, nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for *: 'complex' and 'NoneType'")}, 184 {Mul, None, NewComplex(1 + 3i).ToObject(), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for *: 'NoneType' and 'complex'")}, 185 {Mul, NewFloat(math.NaN()).ToObject(), NewComplex(3i).ToObject(), NewComplex(complex(math.NaN(), math.NaN())).ToObject(), nil}, 186 {Mul, NewComplex(cmplx.NaN()).ToObject(), NewComplex(3i).ToObject(), NewComplex(cmplx.NaN()).ToObject(), nil}, 187 {Mul, NewFloat(math.Inf(-1)).ToObject(), NewComplex(complex(math.Inf(-1), 3)).ToObject(), NewComplex(complex(math.Inf(1), math.NaN())).ToObject(), nil}, 188 {Pow, NewComplex(0i).ToObject(), NewComplex(0i).ToObject(), NewComplex(1 + 0i).ToObject(), nil}, 189 {Pow, NewComplex(-1 + 0i).ToObject(), NewComplex(1i).ToObject(), NewComplex(0.04321391826377226 + 0i).ToObject(), nil}, 190 {Pow, NewComplex(1 + 2i).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(-0.22251715680177264 + 0.10070913113607538i).ToObject(), nil}, 191 {Pow, NewComplex(0i).ToObject(), NewComplex(-1 + 0i).ToObject(), NewComplex(complex(math.Inf(1), 0)).ToObject(), nil}, 192 {Pow, NewComplex(0i).ToObject(), NewComplex(-1 + 1i).ToObject(), NewComplex(complex(math.Inf(1), math.Inf(1))).ToObject(), nil}, 193 {Pow, NewComplex(complex(math.Inf(-1), 2)).ToObject(), NewComplex(1 + 2i).ToObject(), NewComplex(complex(math.NaN(), math.NaN())).ToObject(), nil}, 194 {Pow, NewComplex(1 + 2i).ToObject(), NewComplex(complex(1, math.Inf(1))).ToObject(), NewComplex(complex(math.NaN(), math.NaN())).ToObject(), nil}, 195 {Pow, NewComplex(complex(math.NaN(), 1)).ToObject(), NewComplex(3 + 4i).ToObject(), NewComplex(complex(math.NaN(), math.NaN())).ToObject(), nil}, 196 {Pow, NewComplex(3 + 4i).ToObject(), NewInt(3).ToObject(), NewComplex(-117 + 44.00000000000003i).ToObject(), nil}, 197 {Pow, NewComplex(3 + 4i).ToObject(), NewFloat(3.1415).ToObject(), NewComplex(-152.8892667678244 + 35.555335130496516i).ToObject(), nil}, 198 {Pow, NewComplex(3 + 4i).ToObject(), NewLong(big.NewInt(123)).ToObject(), NewComplex(5.393538720276193e+85 + 7.703512580443326e+85i).ToObject(), nil}, 199 {Pow, NewComplex(1 + 2i).ToObject(), NewStr("foo").ToObject(), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for **: 'complex' and 'str'")}, 200 {Pow, NewStr("foo").ToObject(), NewComplex(1 + 2i).ToObject(), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for **: 'str' and 'complex'")}, 201 } 202 203 for _, cas := range cases { 204 switch got, result := checkInvokeResult(wrapFuncForTest(cas.fun), []*Object{cas.v, cas.w}, cas.want, cas.wantExc); result { 205 case checkInvokeResultExceptionMismatch: 206 t.Errorf("%s(%v, %v) raised %v, want %v", getFuncName(cas.fun), cas.v, cas.w, got, cas.wantExc) 207 case checkInvokeResultReturnValueMismatch: 208 if got == nil || cas.want == nil || !got.isInstance(ComplexType) || !cas.want.isInstance(ComplexType) || 209 !complexesAreSame(toComplexUnsafe(got).Value(), toComplexUnsafe(cas.want).Value()) { 210 t.Errorf("%s(%v, %v) = %v, want %v", getFuncName(cas.fun), cas.v, cas.w, got, cas.want) 211 } 212 } 213 } 214 } 215 216 func TestComplexCompareNotSupported(t *testing.T) { 217 cases := []invokeTestCase{ 218 {args: wrapArgs(complex(1, 2), 1), wantExc: mustCreateException(TypeErrorType, "no ordering relation is defined for complex numbers")}, 219 {args: wrapArgs(complex(1, 2), 1.2), wantExc: mustCreateException(TypeErrorType, "no ordering relation is defined for complex numbers")}, 220 {args: wrapArgs(complex(1, 2), math.NaN()), wantExc: mustCreateException(TypeErrorType, "no ordering relation is defined for complex numbers")}, 221 {args: wrapArgs(complex(1, 2), math.Inf(-1)), wantExc: mustCreateException(TypeErrorType, "no ordering relation is defined for complex numbers")}, 222 {args: wrapArgs(complex(1, 2), "abc"), want: NotImplemented}, 223 } 224 for _, cas := range cases { 225 if err := runInvokeTestCase(wrapFuncForTest(complexCompareNotSupported), &cas); err != "" { 226 t.Error(err) 227 } 228 } 229 } 230 231 func TestComplexDivMod(t *testing.T) { 232 cases := []invokeTestCase{ 233 {args: wrapArgs((1 + 2i), (1 + 2i)), want: NewTuple2(NewComplex(1+0i).ToObject(), NewComplex(0i).ToObject()).ToObject()}, 234 {args: wrapArgs((3 + 4i), (1 + 2i)), want: NewTuple2(NewComplex(2-0i).ToObject(), NewComplex(1+0i).ToObject()).ToObject()}, 235 {args: wrapArgs((3.14 - 0.618i), (-0.123e-4 + 0.151692i)), want: NewTuple2(NewComplex(-5-0i).ToObject(), NewComplex(3.1399385+0.14045999999999992i).ToObject()).ToObject()}, 236 {args: wrapArgs(3, (3 - 4i)), want: NewTuple2(NewComplex(0i).ToObject(), NewComplex(3+0i).ToObject()).ToObject()}, 237 {args: wrapArgs((3 + 4i), -5), want: NewTuple2(NewComplex(-1+0i).ToObject(), NewComplex(-2+4i).ToObject()).ToObject()}, 238 {args: wrapArgs(1.2, (1 - 2i)), want: NewTuple2(NewComplex(0i).ToObject(), NewComplex(1.2+0i).ToObject()).ToObject()}, 239 {args: wrapArgs((1 + 2i), -3.4), want: NewTuple2(NewComplex(-1+0i).ToObject(), NewComplex(-2.4+2i).ToObject()).ToObject()}, 240 {args: wrapArgs(big.NewInt(123), (3 + 4i)), want: NewTuple2(NewComplex(14-0i).ToObject(), NewComplex(81-56i).ToObject()).ToObject()}, 241 {args: wrapArgs((3 - 4i), big.NewInt(-34)), want: NewTuple2(NewComplex(-1+0i).ToObject(), NewComplex(-31-4i).ToObject()).ToObject()}, 242 {args: wrapArgs((3 + 4i), complex(math.Inf(1), math.Inf(-1))), want: NewTuple2(NewComplex(0i).ToObject(), NewComplex(complex(math.NaN(), math.NaN())).ToObject()).ToObject()}, 243 {args: wrapArgs((3 + 4i), complex(math.Inf(1), 2)), want: NewTuple2(NewComplex(0i).ToObject(), NewComplex(complex(math.NaN(), math.NaN())).ToObject()).ToObject()}, 244 {args: wrapArgs(complex(math.Inf(1), math.Inf(1)), (1 + 2i)), want: NewTuple2(NewComplex(complex(math.Inf(1), 0)).ToObject(), NewComplex(complex(math.NaN(), math.NaN())).ToObject()).ToObject()}, 245 {args: wrapArgs(complex(math.Inf(1), 4), (1 + 2i)), want: NewTuple2(NewComplex(complex(math.Inf(1), 0)).ToObject(), NewComplex(complex(math.NaN(), math.Inf(-1))).ToObject()).ToObject()}, 246 {args: wrapArgs(complex(3, math.Inf(1)), (1 + 2i)), want: NewTuple2(NewComplex(complex(math.Inf(1), 0)).ToObject(), NewComplex(complex(math.Inf(-1), math.NaN())).ToObject()).ToObject()}, 247 {args: wrapArgs(complex(3, math.NaN()), (1 + 2i)), want: NewTuple2(NewComplex(complex(math.NaN(), 0)).ToObject(), NewComplex(complex(math.NaN(), math.NaN())).ToObject()).ToObject()}, 248 {args: wrapArgs("foo", (1 + 2i)), wantExc: mustCreateException(TypeErrorType, "unsupported operand type(s) for divmod(): 'str' and 'complex'")}, 249 {args: wrapArgs((3 + 4i), (0 + 0i)), wantExc: mustCreateException(ZeroDivisionErrorType, "complex division or modulo by zero")}, 250 {args: wrapArgs(complex(math.Inf(1), math.NaN()), (0 + 0i)), wantExc: mustCreateException(ZeroDivisionErrorType, "complex division or modulo by zero")}, 251 {args: wrapArgs((3 + 4i), bigLongNumber), wantExc: mustCreateException(OverflowErrorType, "long int too large to convert to complex")}, 252 } 253 for _, cas := range cases { 254 switch got, result := checkInvokeResult(wrapFuncForTest(DivMod), cas.args, cas.want, cas.wantExc); result { 255 case checkInvokeResultExceptionMismatch: 256 t.Errorf("complex.__divmod__%v raised %v, want %v", cas.args, got, cas.wantExc) 257 case checkInvokeResultReturnValueMismatch: 258 // Handle NaN specially, since NaN != NaN. 259 if got == nil || cas.want == nil || !got.isInstance(TupleType) || !cas.want.isInstance(TupleType) || !tupleComplexesAreSame(got, cas.want) { 260 t.Errorf("complex.__divmod__%v = %v, want %v", cas.args, got, cas.want) 261 } 262 } 263 } 264 } 265 266 func TestComplexNE(t *testing.T) { 267 cases := []invokeTestCase{ 268 {args: wrapArgs(complex(0, 0), 0), want: False.ToObject()}, 269 {args: wrapArgs(complex(1, 0), 0), want: True.ToObject()}, 270 {args: wrapArgs(complex(-12, 0), -12), want: False.ToObject()}, 271 {args: wrapArgs(complex(-12, 0), 1), want: True.ToObject()}, 272 {args: wrapArgs(complex(17.20, 0), 17.20), want: False.ToObject()}, 273 {args: wrapArgs(complex(1.2, 0), 17.20), want: True.ToObject()}, 274 {args: wrapArgs(complex(-4, 15), complex(-4, 15)), want: False.ToObject()}, 275 {args: wrapArgs(complex(-4, 15), complex(1, 2)), want: True.ToObject()}, 276 {args: wrapArgs(complex(math.Inf(1), 0), complex(math.Inf(1), 0)), want: False.ToObject()}, 277 {args: wrapArgs(complex(math.Inf(1), 0), complex(0, math.Inf(1))), want: True.ToObject()}, 278 {args: wrapArgs(complex(math.Inf(-1), 0), complex(math.Inf(-1), 0)), want: False.ToObject()}, 279 {args: wrapArgs(complex(math.Inf(-1), 0), complex(0, math.Inf(-1))), want: True.ToObject()}, 280 {args: wrapArgs(complex(math.Inf(1), math.Inf(1)), complex(math.Inf(1), math.Inf(1))), want: False.ToObject()}, 281 } 282 for _, cas := range cases { 283 if err := runInvokeTestCase(wrapFuncForTest(complexNE), &cas); err != "" { 284 t.Error(err) 285 } 286 } 287 } 288 289 func TestComplexNew(t *testing.T) { 290 complexNew := mustNotRaise(GetAttr(NewRootFrame(), ComplexType.ToObject(), NewStr("__new__"), nil)) 291 goodSlotType := newTestClass("GoodSlot", []*Type{ObjectType}, newStringDict(map[string]*Object{ 292 "__complex__": newBuiltinFunction("__complex__", func(_ *Frame, _ Args, _ KWArgs) (*Object, *BaseException) { 293 return NewComplex(complex(1, 2)).ToObject(), nil 294 }).ToObject(), 295 })) 296 badSlotType := newTestClass("BadSlot", []*Type{ObjectType}, newStringDict(map[string]*Object{ 297 "__complex__": newBuiltinFunction("__complex__", func(_ *Frame, _ Args, _ KWArgs) (*Object, *BaseException) { 298 return newObject(ObjectType), nil 299 }).ToObject(), 300 })) 301 strictEqType := newTestClassStrictEq("StrictEq", ComplexType) 302 newStrictEq := func(v complex128) *Object { 303 f := Complex{Object: Object{typ: strictEqType}, value: v} 304 return f.ToObject() 305 } 306 subType := newTestClass("SubType", []*Type{ComplexType}, newStringDict(map[string]*Object{})) 307 subTypeObject := (&Complex{Object: Object{typ: subType}, value: 3.14}).ToObject() 308 slotSubTypeType := newTestClass("SlotSubType", []*Type{ObjectType}, newStringDict(map[string]*Object{ 309 "__complex__": newBuiltinFunction("__complex__", func(_ *Frame, _ Args, _ KWArgs) (*Object, *BaseException) { 310 return subTypeObject, nil 311 }).ToObject(), 312 })) 313 cases := []invokeTestCase{ 314 {args: wrapArgs(ComplexType), want: NewComplex(0).ToObject()}, 315 {args: wrapArgs(ComplexType, 56), want: NewComplex(complex(56, 0)).ToObject()}, 316 {args: wrapArgs(ComplexType, -12), want: NewComplex(complex(-12, 0)).ToObject()}, 317 {args: wrapArgs(ComplexType, 3.14), want: NewComplex(complex(3.14, 0)).ToObject()}, 318 {args: wrapArgs(ComplexType, -703.4), want: NewComplex(complex(-703.4, 0)).ToObject()}, 319 {args: wrapArgs(ComplexType, math.NaN()), want: NewComplex(complex(math.NaN(), 0)).ToObject()}, 320 {args: wrapArgs(ComplexType, math.Inf(1)), want: NewComplex(complex(math.Inf(1), 0)).ToObject()}, 321 {args: wrapArgs(ComplexType, math.Inf(-1)), want: NewComplex(complex(math.Inf(-1), 0)).ToObject()}, 322 {args: wrapArgs(ComplexType, biggestFloat), want: NewComplex(complex(math.MaxFloat64, 0)).ToObject()}, 323 {args: wrapArgs(ComplexType, new(big.Int).Neg(biggestFloat)), want: NewComplex(complex(-math.MaxFloat64, 0)).ToObject()}, 324 {args: wrapArgs(ComplexType, new(big.Int).Sub(big.NewInt(-1), biggestFloat)), wantExc: mustCreateException(OverflowErrorType, "long int too large to convert to float")}, 325 {args: wrapArgs(ComplexType, new(big.Int).Add(biggestFloat, big.NewInt(1))), wantExc: mustCreateException(OverflowErrorType, "long int too large to convert to float")}, 326 {args: wrapArgs(ComplexType, bigLongNumber), wantExc: mustCreateException(OverflowErrorType, "long int too large to convert to float")}, 327 {args: wrapArgs(ComplexType, complex(1, 2)), want: NewComplex(complex(1, 2)).ToObject()}, 328 {args: wrapArgs(ComplexType, complex(-0.0001e-1, 3.14151692)), want: NewComplex(complex(-0.00001, 3.14151692)).ToObject()}, 329 {args: wrapArgs(ComplexType, "23"), want: NewComplex(complex(23, 0)).ToObject()}, 330 {args: wrapArgs(ComplexType, "-516"), want: NewComplex(complex(-516, 0)).ToObject()}, 331 {args: wrapArgs(ComplexType, "1.003e4"), want: NewComplex(complex(10030, 0)).ToObject()}, 332 {args: wrapArgs(ComplexType, "151.7"), want: NewComplex(complex(151.7, 0)).ToObject()}, 333 {args: wrapArgs(ComplexType, "-74.02"), want: NewComplex(complex(-74.02, 0)).ToObject()}, 334 {args: wrapArgs(ComplexType, "+38.29"), want: NewComplex(complex(38.29, 0)).ToObject()}, 335 {args: wrapArgs(ComplexType, "8j"), want: NewComplex(complex(0, 8)).ToObject()}, 336 {args: wrapArgs(ComplexType, "-17j"), want: NewComplex(complex(0, -17)).ToObject()}, 337 {args: wrapArgs(ComplexType, "7.3j"), want: NewComplex(complex(0, 7.3)).ToObject()}, 338 {args: wrapArgs(ComplexType, "-4.786j"), want: NewComplex(complex(0, -4.786)).ToObject()}, 339 {args: wrapArgs(ComplexType, "+17.59123j"), want: NewComplex(complex(0, 17.59123)).ToObject()}, 340 {args: wrapArgs(ComplexType, "-3.0007e3j"), want: NewComplex(complex(0, -3000.7)).ToObject()}, 341 {args: wrapArgs(ComplexType, "1+2j"), want: NewComplex(complex(1, 2)).ToObject()}, 342 {args: wrapArgs(ComplexType, "3.1415-23j"), want: NewComplex(complex(3.1415, -23)).ToObject()}, 343 {args: wrapArgs(ComplexType, "-23+3.1415j"), want: NewComplex(complex(-23, 3.1415)).ToObject()}, 344 {args: wrapArgs(ComplexType, "+451.2192+384.27j"), want: NewComplex(complex(451.2192, 384.27)).ToObject()}, 345 {args: wrapArgs(ComplexType, "-38.378-283.28j"), want: NewComplex(complex(-38.378, -283.28)).ToObject()}, 346 {args: wrapArgs(ComplexType, "1.76123e2+0.000007e6j"), want: NewComplex(complex(176.123, 7)).ToObject()}, 347 {args: wrapArgs(ComplexType, "-nan+nanj"), want: NewComplex(complex(math.NaN(), math.NaN())).ToObject()}, 348 {args: wrapArgs(ComplexType, "inf-infj"), want: NewComplex(complex(math.Inf(1), math.Inf(-1))).ToObject()}, 349 {args: wrapArgs(ComplexType, 1, 2), want: NewComplex(complex(1, 2)).ToObject()}, 350 {args: wrapArgs(ComplexType, 7, 23.45), want: NewComplex(complex(7, 23.45)).ToObject()}, 351 {args: wrapArgs(ComplexType, 28.2537, -19), want: NewComplex(complex(28.2537, -19)).ToObject()}, 352 {args: wrapArgs(ComplexType, -3.14, -0.685), want: NewComplex(complex(-3.14, -0.685)).ToObject()}, 353 {args: wrapArgs(ComplexType, -47.234e+2, 2.374e+3), want: NewComplex(complex(-4723.4, 2374)).ToObject()}, 354 {args: wrapArgs(ComplexType, -4.5, new(big.Int).Neg(biggestFloat)), want: NewComplex(complex(-4.5, -math.MaxFloat64)).ToObject()}, 355 {args: wrapArgs(ComplexType, biggestFloat, biggestFloat), want: NewComplex(complex(math.MaxFloat64, math.MaxFloat64)).ToObject()}, 356 {args: wrapArgs(ComplexType, 5, math.NaN()), want: NewComplex(complex(5, math.NaN())).ToObject()}, 357 {args: wrapArgs(ComplexType, math.Inf(-1), -95), want: NewComplex(complex(math.Inf(-1), -95)).ToObject()}, 358 {args: wrapArgs(ComplexType, math.NaN(), math.NaN()), want: NewComplex(complex(math.NaN(), math.NaN())).ToObject()}, 359 {args: wrapArgs(ComplexType, math.Inf(1), math.Inf(-1)), want: NewComplex(complex(math.Inf(1), math.Inf(-1))).ToObject()}, 360 {args: wrapArgs(ComplexType, complex(-48.8, 0.7395), 5.448), want: NewComplex(complex(-48.8, 6.1875)).ToObject()}, 361 {args: wrapArgs(ComplexType, -3.14, complex(-4.5, -0.618)), want: NewComplex(complex(-2.5220000000000002, -4.5)).ToObject()}, 362 {args: wrapArgs(ComplexType, complex(1, 2), complex(3, 4)), want: NewComplex(complex(-3, 5)).ToObject()}, 363 {args: wrapArgs(ComplexType, complex(-2.47, 0.205e+2), complex(3.1, -0.4)), want: NewComplex(complex(-2.0700000000000003, 23.6)).ToObject()}, 364 {args: wrapArgs(ComplexType, "bar", 1.2), wantExc: mustCreateException(TypeErrorType, "complex() can't take second arg if first is a string")}, 365 {args: wrapArgs(ComplexType, "bar", None), wantExc: mustCreateException(TypeErrorType, "complex() can't take second arg if first is a string")}, 366 {args: wrapArgs(ComplexType, 1.2, "baz"), wantExc: mustCreateException(TypeErrorType, "complex() second arg can't be a string")}, 367 {args: wrapArgs(ComplexType, None, "baz"), wantExc: mustCreateException(TypeErrorType, "complex() second arg can't be a string")}, 368 {args: wrapArgs(ComplexType, newObject(goodSlotType)), want: NewComplex(complex(1, 2)).ToObject()}, 369 {args: wrapArgs(ComplexType, newObject(badSlotType)), wantExc: mustCreateException(TypeErrorType, "__complex__ returned non-complex (type object)")}, 370 {args: wrapArgs(ComplexType, newObject(slotSubTypeType)), want: subTypeObject}, 371 {args: wrapArgs(strictEqType, 3.14), want: newStrictEq(3.14)}, 372 {args: wrapArgs(strictEqType, newObject(goodSlotType)), want: newStrictEq(complex(1, 2))}, 373 {args: wrapArgs(strictEqType, newObject(badSlotType)), wantExc: mustCreateException(TypeErrorType, "__complex__ returned non-complex (type object)")}, 374 {args: wrapArgs(), wantExc: mustCreateException(TypeErrorType, "'__new__' requires 1 arguments")}, 375 {args: wrapArgs(FloatType), wantExc: mustCreateException(TypeErrorType, "complex.__new__(float): float is not a subtype of complex")}, 376 {args: wrapArgs(ComplexType, None), wantExc: mustCreateException(TypeErrorType, "complex() argument must be a string or a number")}, 377 {args: wrapArgs(ComplexType, "foo"), wantExc: mustCreateException(ValueErrorType, "complex() arg is a malformed string")}, 378 {args: wrapArgs(ComplexType, 123, None, None), wantExc: mustCreateException(TypeErrorType, "'__new__' of 'complex' requires at most 2 arguments")}, 379 } 380 for _, cas := range cases { 381 switch got, match := checkInvokeResult(complexNew, cas.args, cas.want, cas.wantExc); match { 382 case checkInvokeResultExceptionMismatch: 383 t.Errorf("complex.__new__%v raised %v, want %v", cas.args, got, cas.wantExc) 384 case checkInvokeResultReturnValueMismatch: 385 // Handle NaN specially, since NaN != NaN. 386 if got == nil || cas.want == nil || !got.isInstance(ComplexType) || !cas.want.isInstance(ComplexType) || 387 !cmplx.IsNaN(toComplexUnsafe(got).Value()) || !cmplx.IsNaN(toComplexUnsafe(cas.want).Value()) { 388 t.Errorf("complex.__new__%v = %v, want %v", cas.args, got, cas.want) 389 } 390 } 391 } 392 } 393 394 func TestComplexNonZero(t *testing.T) { 395 cases := []invokeTestCase{ 396 {args: wrapArgs(complex(0, 0)), want: False.ToObject()}, 397 {args: wrapArgs(complex(.0, .0)), want: False.ToObject()}, 398 {args: wrapArgs(complex(0.0, 0.1)), want: True.ToObject()}, 399 {args: wrapArgs(complex(1, 0)), want: True.ToObject()}, 400 {args: wrapArgs(complex(3.14, -0.001e+5)), want: True.ToObject()}, 401 {args: wrapArgs(complex(math.NaN(), math.NaN())), want: True.ToObject()}, 402 {args: wrapArgs(complex(math.Inf(-1), math.Inf(1))), want: True.ToObject()}, 403 } 404 for _, cas := range cases { 405 if err := runInvokeTestCase(wrapFuncForTest(complexNonZero), &cas); err != "" { 406 t.Error(err) 407 } 408 } 409 } 410 411 func TestComplexPos(t *testing.T) { 412 cases := []invokeTestCase{ 413 {args: wrapArgs(complex(0, 0)), want: NewComplex(complex(0, 0)).ToObject()}, 414 {args: wrapArgs(complex(42, -0.1)), want: NewComplex(complex(42, -0.1)).ToObject()}, 415 {args: wrapArgs(complex(-1.2, 375e+2)), want: NewComplex(complex(-1.2, 37500)).ToObject()}, 416 {args: wrapArgs(complex(5, math.NaN())), want: NewComplex(complex(5, math.NaN())).ToObject()}, 417 {args: wrapArgs(complex(math.Inf(1), 0.618)), want: NewComplex(complex(math.Inf(1), 0.618)).ToObject()}, 418 } 419 for _, cas := range cases { 420 switch got, match := checkInvokeResult(wrapFuncForTest(complexPos), cas.args, cas.want, cas.wantExc); match { 421 case checkInvokeResultReturnValueMismatch: 422 if got == nil || cas.want == nil || !got.isInstance(ComplexType) || !cas.want.isInstance(ComplexType) || 423 !complexesAreSame(toComplexUnsafe(got).Value(), toComplexUnsafe(cas.want).Value()) { 424 t.Errorf("complex.__pos__%v = %v, want %v", cas.args, got, cas.want) 425 } 426 } 427 } 428 } 429 430 func TestComplexRepr(t *testing.T) { 431 cases := []invokeTestCase{ 432 {args: wrapArgs(complex(0.0, 0.0)), want: NewStr("0j").ToObject()}, 433 {args: wrapArgs(complex(0.0, 1.0)), want: NewStr("1j").ToObject()}, 434 {args: wrapArgs(complex(1.0, 2.0)), want: NewStr("(1+2j)").ToObject()}, 435 {args: wrapArgs(complex(3.1, -4.2)), want: NewStr("(3.1-4.2j)").ToObject()}, 436 {args: wrapArgs(complex(math.NaN(), math.NaN())), want: NewStr("(nan+nanj)").ToObject()}, 437 {args: wrapArgs(complex(math.Inf(-1), math.Inf(1))), want: NewStr("(-inf+infj)").ToObject()}, 438 {args: wrapArgs(complex(math.Inf(1), math.Inf(-1))), want: NewStr("(inf-infj)").ToObject()}, 439 } 440 for _, cas := range cases { 441 if err := runInvokeTestCase(wrapFuncForTest(Repr), &cas); err != "" { 442 t.Error(err) 443 } 444 } 445 } 446 447 func TestParseComplex(t *testing.T) { 448 var ErrSyntax = errors.New("invalid syntax") 449 cases := []struct { 450 s string 451 want complex128 452 err error 453 }{ 454 {"5", complex(5, 0), nil}, 455 {"-3.14", complex(-3.14, 0), nil}, 456 {"1.8456e3", complex(1845.6, 0), nil}, 457 {"23j", complex(0, 23), nil}, 458 {"7j", complex(0, 7), nil}, 459 {"-365.12j", complex(0, -365.12), nil}, 460 {"1+2j", complex(1, 2), nil}, 461 {"-.3+.7j", complex(-0.3, 0.7), nil}, 462 {"-1.3+2.7j", complex(-1.3, 2.7), nil}, 463 {"48.39-20.3j", complex(48.39, -20.3), nil}, 464 {"-1.23e2-30.303j", complex(-123, -30.303), nil}, 465 {"-1.23e2-45.678e1j", complex(-123, -456.78), nil}, 466 {"nan+nanj", complex(math.NaN(), math.NaN()), nil}, 467 {"nan-nanj", complex(math.NaN(), math.NaN()), nil}, 468 {"-nan-nanj", complex(math.NaN(), math.NaN()), nil}, 469 {"inf+infj", complex(math.Inf(1), math.Inf(1)), nil}, 470 {"inf-infj", complex(math.Inf(1), math.Inf(-1)), nil}, 471 {"-inf-infj", complex(math.Inf(-1), math.Inf(-1)), nil}, 472 {"infINIty+infinityj", complex(math.Inf(1), math.Inf(1)), nil}, 473 {"3.4+j", complex(3.4, 1), nil}, 474 {"21.98-j", complex(21.98, -1), nil}, 475 {"+j", complex(0, 1), nil}, 476 {"-j", complex(0, -1), nil}, 477 {"j", complex(0, 1), nil}, 478 {"(2.1-3.4j)", complex(2.1, -3.4), nil}, 479 {" (2.1-3.4j) ", complex(2.1, -3.4), nil}, 480 {" ( 2.1-3.4j ) ", complex(2.1, -3.4), nil}, 481 {" \t \n \r ( \t \n \r 2.1-3.4j \t \n \r ) \t \n \r ", complex(2.1, -3.4), nil}, 482 {" 3.14-15.16j ", complex(3.14, -15.16), nil}, 483 {"(2.1-3.4j", complex(0, 0), ErrSyntax}, 484 {"((2.1-3.4j))", complex(0, 0), ErrSyntax}, 485 {"3.14 -15.16j", complex(0, 0), ErrSyntax}, 486 {"3.14- 15.16j", complex(0, 0), ErrSyntax}, 487 {"3.14-15.16 j", complex(0, 0), ErrSyntax}, 488 {"3.14 - 15.16 j", complex(0, 0), ErrSyntax}, 489 {"foo", complex(0, 0), ErrSyntax}, 490 {"foo+bar", complex(0, 0), ErrSyntax}, 491 } 492 for _, cas := range cases { 493 if got, _ := parseComplex(cas.s); !complexesAreSame(got, cas.want) { 494 t.Errorf("parseComplex(%q) = %g, want %g", cas.s, got, cas.want) 495 } 496 } 497 } 498 499 func TestComplexHash(t *testing.T) { 500 cases := []invokeTestCase{ 501 {args: wrapArgs(complex(0.0, 0.0)), want: NewInt(0).ToObject()}, 502 {args: wrapArgs(complex(0.0, 1.0)), want: NewInt(1000003).ToObject()}, 503 {args: wrapArgs(complex(1.0, 0.0)), want: NewInt(1).ToObject()}, 504 {args: wrapArgs(complex(3.1, -4.2)), want: NewInt(-1556830019620134).ToObject()}, 505 {args: wrapArgs(complex(3.1, 4.2)), want: NewInt(1557030815934348).ToObject()}, 506 } 507 for _, cas := range cases { 508 if err := runInvokeTestCase(wrapFuncForTest(complexHash), &cas); err != "" { 509 t.Error(err) 510 } 511 } 512 } 513 514 func floatsAreSame(a, b float64) bool { 515 return a == b || (math.IsNaN(a) && math.IsNaN(b)) 516 } 517 518 func complexesAreSame(a, b complex128) bool { 519 return floatsAreSame(real(a), real(b)) && floatsAreSame(imag(a), imag(b)) 520 } 521 522 func tupleComplexesAreSame(got, want *Object) bool { 523 if toTupleUnsafe(got).Len() != toTupleUnsafe(want).Len() { 524 return false 525 } 526 for i := 0; i < toTupleUnsafe(got).Len(); i++ { 527 if !complexesAreSame(toComplexUnsafe(toTupleUnsafe(got).GetItem(i)).Value(), toComplexUnsafe(toTupleUnsafe(want).GetItem(i)).Value()) { 528 return false 529 } 530 } 531 return true 532 }