github.com/google/grumpy@v0.0.0-20171122020858-3ec87959189c/runtime/builtin_types_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 grumpy 16 17 import ( 18 "bytes" 19 "fmt" 20 "io" 21 "math/big" 22 "os" 23 "testing" 24 ) 25 26 func TestBuiltinDelAttr(t *testing.T) { 27 f := NewRootFrame() 28 delattr := mustNotRaise(Builtins.GetItemString(f, "delattr")) 29 fooType := newTestClass("Foo", []*Type{ObjectType}, NewDict()) 30 fooForDelAttr := newObject(fooType) 31 fooValue := newObject(ObjectType) 32 mustNotRaise(nil, SetAttr(f, fooForDelAttr, NewStr("bar"), fooValue)) 33 fun := wrapFuncForTest(func(f *Frame, args ...*Object) (*Object, *BaseException) { 34 result, raised := delattr.Call(f, args, nil) 35 if raised != nil { 36 return nil, raised 37 } 38 val, raised := GetAttr(f, args[0], toStrUnsafe(args[1]), None) 39 return newTestTuple(result, val == fooValue).ToObject(), nil 40 }) 41 cases := []invokeTestCase{ 42 {args: wrapArgs(fooForDelAttr, "bar"), want: newTestTuple(None, False.ToObject()).ToObject()}, 43 {args: wrapArgs(fooForDelAttr, "baz"), wantExc: mustCreateException(AttributeErrorType, "'Foo' object has no attribute 'baz'")}, 44 {args: wrapArgs(fooForDelAttr), wantExc: mustCreateException(TypeErrorType, "'delattr' requires 2 arguments")}, 45 {args: wrapArgs(fooForDelAttr, "foo", "bar"), wantExc: mustCreateException(TypeErrorType, "'delattr' requires 2 arguments")}, 46 } 47 for _, cas := range cases { 48 if err := runInvokeTestCase(fun, &cas); err != "" { 49 t.Error(err) 50 } 51 } 52 } 53 54 func TestBuiltinFuncs(t *testing.T) { 55 f := NewRootFrame() 56 objectDir := ObjectType.Dict().Keys(f) 57 objectDir.Sort(f) 58 fooType := newTestClass("Foo", []*Type{ObjectType}, newStringDict(map[string]*Object{"bar": None})) 59 fooTypeDir := NewList(objectDir.elems...) 60 fooTypeDir.Append(NewStr("bar").ToObject()) 61 fooTypeDir.Sort(f) 62 foo := newObject(fooType) 63 SetAttr(f, foo, NewStr("baz"), None) 64 fooDir := NewList(fooTypeDir.elems...) 65 fooDir.Append(NewStr("baz").ToObject()) 66 fooDir.Sort(f) 67 dirModule := newTestModule("foo", "foo.py") 68 if raised := dirModule.Dict().SetItemString(NewRootFrame(), "bar", newObject(ObjectType)); raised != nil { 69 panic(raised) 70 } 71 dirModuleDir := dirModule.Dict().Keys(NewRootFrame()) 72 if raised := dirModuleDir.Sort(NewRootFrame()); raised != nil { 73 panic(raised) 74 } 75 iter := mustNotRaise(Iter(f, mustNotRaise(xrangeType.Call(f, wrapArgs(5), nil)))) 76 neg := wrapFuncForTest(func(f *Frame, i int) int { return -i }) 77 raiseKey := wrapFuncForTest(func(f *Frame, o *Object) *BaseException { return f.RaiseType(RuntimeErrorType, "foo") }) 78 hexOctType := newTestClass("HexOct", []*Type{ObjectType}, newStringDict(map[string]*Object{ 79 "__hex__": newBuiltinFunction("__hex__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) { 80 return NewStr("0xhexadecimal").ToObject(), nil 81 }).ToObject(), 82 "__oct__": newBuiltinFunction("__hex__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) { 83 return NewStr("0octal").ToObject(), nil 84 }).ToObject(), 85 })) 86 badNonZeroType := newTestClass("BadNonZeroType", []*Type{ObjectType}, newStringDict(map[string]*Object{ 87 "__nonzero__": newBuiltinFunction("__nonzero__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) { 88 return nil, f.RaiseType(RuntimeErrorType, "foo") 89 }).ToObject(), 90 })) 91 badNextType := newTestClass("BadNextType", []*Type{ObjectType}, newStringDict(map[string]*Object{ 92 "next": newBuiltinFunction("next", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) { 93 return nil, f.RaiseType(RuntimeErrorType, "foo") 94 }).ToObject(), 95 })) 96 badIterType := newTestClass("BadIterType", []*Type{ObjectType}, newStringDict(map[string]*Object{ 97 "__iter__": newBuiltinFunction("__iter__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) { 98 return newObject(badNextType), nil 99 }).ToObject(), 100 })) 101 addType := newTestClass("Add", []*Type{ObjectType}, newStringDict(map[string]*Object{ 102 "__add__": newBuiltinFunction("__add__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) { 103 return NewInt(1).ToObject(), nil 104 }).ToObject(), 105 })) 106 fooBuiltinFunc := newBuiltinFunction("foo", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) { 107 return newTestTuple(NewTuple(args.makeCopy()...), kwargs.makeDict()).ToObject(), nil 108 }).ToObject() 109 fooFunc := NewFunction(NewCode("foo", "foo.py", nil, CodeFlagVarArg, func(f *Frame, args []*Object) (*Object, *BaseException) { 110 return args[0], nil 111 }), nil) 112 cases := []struct { 113 f string 114 args Args 115 kwargs KWArgs 116 want *Object 117 wantExc *BaseException 118 }{ 119 {f: "abs", args: wrapArgs(1, 2, 3), wantExc: mustCreateException(TypeErrorType, "'abs' requires 1 arguments")}, 120 {f: "abs", args: wrapArgs(1), want: NewInt(1).ToObject()}, 121 {f: "abs", args: wrapArgs(-1), want: NewInt(1).ToObject()}, 122 {f: "abs", args: wrapArgs(big.NewInt(2)), want: NewLong(big.NewInt(2)).ToObject()}, 123 {f: "abs", args: wrapArgs(big.NewInt(-2)), want: NewLong(big.NewInt(2)).ToObject()}, 124 {f: "abs", args: wrapArgs(NewFloat(3.4)), want: NewFloat(3.4).ToObject()}, 125 {f: "abs", args: wrapArgs(NewFloat(-3.4)), want: NewFloat(3.4).ToObject()}, 126 {f: "abs", args: wrapArgs(MinInt), want: NewLong(big.NewInt(MinInt).Neg(minIntBig)).ToObject()}, 127 {f: "abs", args: wrapArgs(NewStr("a")), wantExc: mustCreateException(TypeErrorType, "bad operand type for abs(): 'str'")}, 128 {f: "all", args: wrapArgs(newTestList()), want: True.ToObject()}, 129 {f: "all", args: wrapArgs(newTestList(1, 2, 3)), want: True.ToObject()}, 130 {f: "all", args: wrapArgs(newTestList(1, 0, 1)), want: False.ToObject()}, 131 {f: "all", args: wrapArgs(13), wantExc: mustCreateException(TypeErrorType, "'int' object is not iterable")}, 132 {f: "all", args: wrapArgs(newTestList(newObject(badNonZeroType))), wantExc: mustCreateException(RuntimeErrorType, "foo")}, 133 {f: "all", args: wrapArgs(newObject(badIterType)), wantExc: mustCreateException(RuntimeErrorType, "foo")}, 134 {f: "any", args: wrapArgs(newTestList()), want: False.ToObject()}, 135 {f: "any", args: wrapArgs(newTestList(1, 2, 3)), want: True.ToObject()}, 136 {f: "any", args: wrapArgs(newTestList(1, 0, 1)), want: True.ToObject()}, 137 {f: "any", args: wrapArgs(newTestList(0, 0, 0)), want: False.ToObject()}, 138 {f: "any", args: wrapArgs(newTestList(False.ToObject(), False.ToObject())), want: False.ToObject()}, 139 {f: "any", args: wrapArgs(13), wantExc: mustCreateException(TypeErrorType, "'int' object is not iterable")}, 140 {f: "any", args: wrapArgs(newTestList(newObject(badNonZeroType))), wantExc: mustCreateException(RuntimeErrorType, "foo")}, 141 {f: "any", args: wrapArgs(newObject(badIterType)), wantExc: mustCreateException(RuntimeErrorType, "foo")}, 142 {f: "bin", args: wrapArgs(64 + 8 + 1), want: NewStr("0b1001001").ToObject()}, 143 {f: "bin", args: wrapArgs(MinInt), want: NewStr(fmt.Sprintf("-0b%b0", -(MinInt >> 1))).ToObject()}, 144 {f: "bin", args: wrapArgs(0), want: NewStr("0b0").ToObject()}, 145 {f: "bin", args: wrapArgs(1), want: NewStr("0b1").ToObject()}, 146 {f: "bin", args: wrapArgs(-1), want: NewStr("-0b1").ToObject()}, 147 {f: "bin", args: wrapArgs(big.NewInt(-1)), want: NewStr("-0b1").ToObject()}, 148 {f: "bin", args: wrapArgs("foo"), wantExc: mustCreateException(TypeErrorType, "str object cannot be interpreted as an index")}, 149 {f: "bin", args: wrapArgs(0.1), wantExc: mustCreateException(TypeErrorType, "float object cannot be interpreted as an index")}, 150 {f: "bin", args: wrapArgs(1, 2, 3), wantExc: mustCreateException(TypeErrorType, "'bin' requires 1 arguments")}, 151 {f: "bin", args: wrapArgs(newTestIndexObject(123)), want: NewStr("0b1111011").ToObject()}, 152 {f: "callable", args: wrapArgs(fooBuiltinFunc), want: True.ToObject()}, 153 {f: "callable", args: wrapArgs(fooFunc), want: True.ToObject()}, 154 {f: "callable", args: wrapArgs(0), want: False.ToObject()}, 155 {f: "callable", args: wrapArgs(0.1), want: False.ToObject()}, 156 {f: "callable", args: wrapArgs("foo"), want: False.ToObject()}, 157 {f: "callable", args: wrapArgs(newTestDict("foo", 1, "bar", 2)), want: False.ToObject()}, 158 {f: "callable", args: wrapArgs(newTestList(1, 2, 3)), want: False.ToObject()}, 159 {f: "callable", args: wrapArgs(iter), want: False.ToObject()}, 160 {f: "callable", args: wrapArgs(1, 2), wantExc: mustCreateException(TypeErrorType, "'callable' requires 1 arguments")}, 161 {f: "chr", args: wrapArgs(0), want: NewStr("\x00").ToObject()}, 162 {f: "chr", args: wrapArgs(65), want: NewStr("A").ToObject()}, 163 {f: "chr", args: wrapArgs(300), wantExc: mustCreateException(ValueErrorType, "chr() arg not in range(256)")}, 164 {f: "chr", args: wrapArgs(-1), wantExc: mustCreateException(ValueErrorType, "chr() arg not in range(256)")}, 165 {f: "chr", args: wrapArgs(), wantExc: mustCreateException(TypeErrorType, "'chr' requires 1 arguments")}, 166 {f: "dir", args: wrapArgs(newObject(ObjectType)), want: objectDir.ToObject()}, 167 {f: "dir", args: wrapArgs(newObject(fooType)), want: fooTypeDir.ToObject()}, 168 {f: "dir", args: wrapArgs(fooType), want: fooTypeDir.ToObject()}, 169 {f: "dir", args: wrapArgs(foo), want: fooDir.ToObject()}, 170 {f: "dir", args: wrapArgs(dirModule), want: dirModuleDir.ToObject()}, 171 {f: "dir", args: wrapArgs(), wantExc: mustCreateException(TypeErrorType, "'dir' requires 1 arguments")}, 172 {f: "divmod", args: wrapArgs(12, 7), want: NewTuple2(NewInt(1).ToObject(), NewInt(5).ToObject()).ToObject()}, 173 {f: "divmod", args: wrapArgs(-12, 7), want: NewTuple2(NewInt(-2).ToObject(), NewInt(2).ToObject()).ToObject()}, 174 {f: "divmod", args: wrapArgs(12, -7), want: NewTuple2(NewInt(-2).ToObject(), NewInt(-2).ToObject()).ToObject()}, 175 {f: "divmod", args: wrapArgs(-12, -7), want: NewTuple2(NewInt(1).ToObject(), NewInt(-5).ToObject()).ToObject()}, 176 {f: "divmod", args: wrapArgs(MaxInt, MinInt), want: NewTuple2(NewInt(-1).ToObject(), NewInt(-1).ToObject()).ToObject()}, 177 {f: "divmod", args: wrapArgs(MinInt, MaxInt), want: NewTuple2(NewInt(-2).ToObject(), NewInt(MaxInt-1).ToObject()).ToObject()}, 178 {f: "divmod", args: wrapArgs(MinInt, -1), want: NewTuple2(NewLong(new(big.Int).Neg(minIntBig)).ToObject(), NewLong(big.NewInt(0)).ToObject()).ToObject()}, 179 {f: "divmod", args: wrapArgs(big.NewInt(12), big.NewInt(7)), want: NewTuple2(NewLong(big.NewInt(1)).ToObject(), NewLong(big.NewInt(5)).ToObject()).ToObject()}, 180 {f: "divmod", args: wrapArgs(big.NewInt(-12), big.NewInt(7)), want: NewTuple2(NewLong(big.NewInt(-2)).ToObject(), NewLong(big.NewInt(2)).ToObject()).ToObject()}, 181 {f: "divmod", args: wrapArgs(big.NewInt(12), big.NewInt(-7)), want: NewTuple2(NewLong(big.NewInt(-2)).ToObject(), NewLong(big.NewInt(-2)).ToObject()).ToObject()}, 182 {f: "divmod", args: wrapArgs(big.NewInt(-12), big.NewInt(-7)), want: NewTuple2(NewLong(big.NewInt(1)).ToObject(), NewLong(big.NewInt(-5)).ToObject()).ToObject()}, 183 {f: "divmod", args: wrapArgs(3.25, 1.0), want: NewTuple2(NewFloat(3.0).ToObject(), NewFloat(0.25).ToObject()).ToObject()}, 184 {f: "divmod", args: wrapArgs(-3.25, 1.0), want: NewTuple2(NewFloat(-4.0).ToObject(), NewFloat(0.75).ToObject()).ToObject()}, 185 {f: "divmod", args: wrapArgs(3.25, -1.0), want: NewTuple2(NewFloat(-4.0).ToObject(), NewFloat(-0.75).ToObject()).ToObject()}, 186 {f: "divmod", args: wrapArgs(-3.25, -1.0), want: NewTuple2(NewFloat(3.0).ToObject(), NewFloat(-0.25).ToObject()).ToObject()}, 187 {f: "divmod", args: wrapArgs(NewStr("a"), NewStr("b")), wantExc: mustCreateException(TypeErrorType, "unsupported operand type(s) for divmod(): 'str' and 'str'")}, 188 {f: "divmod", args: wrapArgs(), wantExc: mustCreateException(TypeErrorType, "'divmod' requires 2 arguments")}, 189 {f: "getattr", args: wrapArgs(None, NewStr("foo").ToObject(), NewStr("bar").ToObject()), want: NewStr("bar").ToObject()}, 190 {f: "getattr", args: wrapArgs(None, NewStr("foo").ToObject()), wantExc: mustCreateException(AttributeErrorType, "'NoneType' object has no attribute 'foo'")}, 191 {f: "hasattr", args: wrapArgs(newObject(ObjectType), NewStr("foo").ToObject()), want: False.ToObject()}, 192 {f: "hasattr", args: wrapArgs(foo, NewStr("bar").ToObject()), want: True.ToObject()}, 193 {f: "hasattr", args: wrapArgs(foo, NewStr("baz").ToObject()), want: True.ToObject()}, 194 {f: "hasattr", args: wrapArgs(foo, NewStr("qux").ToObject()), want: False.ToObject()}, 195 {f: "hash", args: wrapArgs(123), want: NewInt(123).ToObject()}, 196 {f: "hash", args: wrapArgs("foo"), want: hashFoo}, 197 {f: "hash", args: wrapArgs(NewList()), wantExc: mustCreateException(TypeErrorType, "unhashable type: 'list'")}, 198 {f: "hex", args: wrapArgs(0x63adbeef), want: NewStr("0x63adbeef").ToObject()}, 199 {f: "hex", args: wrapArgs(0), want: NewStr("0x0").ToObject()}, 200 {f: "hex", args: wrapArgs(1), want: NewStr("0x1").ToObject()}, 201 {f: "hex", args: wrapArgs(-1), want: NewStr("-0x1").ToObject()}, 202 {f: "hex", args: wrapArgs(big.NewInt(-1)), want: NewStr("-0x1L").ToObject()}, 203 {f: "hex", args: wrapArgs("foo"), wantExc: mustCreateException(TypeErrorType, "hex() argument can't be converted to hex")}, 204 {f: "hex", args: wrapArgs(0.1), wantExc: mustCreateException(TypeErrorType, "hex() argument can't be converted to hex")}, 205 {f: "hex", args: wrapArgs(1, 2, 3), wantExc: mustCreateException(TypeErrorType, "'hex' requires 1 arguments")}, 206 {f: "hex", args: wrapArgs(newObject(hexOctType)), want: NewStr("0xhexadecimal").ToObject()}, 207 {f: "id", args: wrapArgs(foo), want: NewInt(int(uintptr(foo.toPointer()))).ToObject()}, 208 {f: "id", args: wrapArgs(), wantExc: mustCreateException(TypeErrorType, "'id' requires 1 arguments")}, 209 {f: "isinstance", args: wrapArgs(NewInt(42).ToObject(), IntType.ToObject()), want: True.ToObject()}, 210 {f: "isinstance", args: wrapArgs(NewStr("foo").ToObject(), TupleType.ToObject()), want: False.ToObject()}, 211 {f: "isinstance", args: wrapArgs(), wantExc: mustCreateException(TypeErrorType, "'isinstance' requires 2 arguments")}, 212 {f: "issubclass", args: wrapArgs(IntType, IntType), want: True.ToObject()}, 213 {f: "issubclass", args: wrapArgs(fooType, IntType), want: False.ToObject()}, 214 {f: "issubclass", args: wrapArgs(fooType, ObjectType), want: True.ToObject()}, 215 {f: "issubclass", args: wrapArgs(FloatType, newTestTuple(IntType, StrType)), want: False.ToObject()}, 216 {f: "issubclass", args: wrapArgs(FloatType, newTestTuple(IntType, FloatType)), want: True.ToObject()}, 217 {f: "issubclass", args: wrapArgs(), wantExc: mustCreateException(TypeErrorType, "'issubclass' requires 2 arguments")}, 218 {f: "iter", args: wrapArgs(iter), want: iter}, 219 {f: "iter", args: wrapArgs(42), wantExc: mustCreateException(TypeErrorType, "'int' object is not iterable")}, 220 {f: "len", args: wrapArgs(newTestList(1, 2, 3)), want: NewInt(3).ToObject()}, 221 {f: "len", args: wrapArgs(), wantExc: mustCreateException(TypeErrorType, "'len' requires 1 arguments")}, 222 {f: "map", args: wrapArgs(), wantExc: mustCreateException(TypeErrorType, "map() requires at least two args")}, 223 {f: "map", args: wrapArgs(StrType), wantExc: mustCreateException(TypeErrorType, "map() requires at least two args")}, 224 {f: "map", args: wrapArgs(None, newTestList()), want: newTestList().ToObject()}, 225 {f: "map", args: wrapArgs(None, newTestList(1, 2, 3)), want: newTestList(1, 2, 3).ToObject()}, 226 {f: "map", args: wrapArgs(None, newTestDict("foo", 1, "bar", 3)), want: newTestList("foo", "bar").ToObject()}, 227 {f: "map", args: wrapArgs(None, None), wantExc: mustCreateException(TypeErrorType, "'NoneType' object is not iterable")}, 228 {f: "map", args: wrapArgs(StrType, None), wantExc: mustCreateException(TypeErrorType, "'NoneType' object is not iterable")}, 229 {f: "map", args: wrapArgs(StrType, newTestList(), None), wantExc: mustCreateException(TypeErrorType, "'NoneType' object is not iterable")}, 230 {f: "map", args: wrapArgs(newTestList(), newTestList(1, 2, 3)), wantExc: mustCreateException(TypeErrorType, "'list' object is not callable")}, 231 {f: "map", args: wrapArgs(StrType, newTestList()), want: newTestList().ToObject()}, 232 {f: "map", args: wrapArgs(StrType, newTestList(1, 2, 3)), want: newTestList("1", "2", "3").ToObject()}, 233 {f: "map", args: wrapArgs(StrType, newTestList(-1, -2, -3)), want: newTestList("-1", "-2", "-3").ToObject()}, 234 {f: "map", args: wrapArgs(IntType, newTestList("1", "2", "3")), want: newTestList(1, 2, 3).ToObject()}, 235 {f: "map", args: wrapArgs(IntType, newTestList("-1", "-2", "-3")), want: newTestList(-1, -2, -3).ToObject()}, 236 {f: "map", args: wrapArgs(IntType, "123"), want: newTestList(1, 2, 3).ToObject()}, 237 {f: "map", args: wrapArgs(IntType, newTestDict("1", "11", "2", "22")), want: newTestList(1, 2).ToObject()}, 238 {f: "map", args: wrapArgs(IntType, 1), wantExc: mustCreateException(TypeErrorType, "'int' object is not iterable")}, 239 {f: "map", args: wrapArgs(1, newTestList(1, 2, 3)), wantExc: mustCreateException(TypeErrorType, "'int' object is not callable")}, 240 {f: "map", args: wrapArgs(StrType, newTestList(), 1), wantExc: mustCreateException(TypeErrorType, "'int' object is not iterable")}, 241 {f: "max", args: wrapArgs(2, 3, 1), want: NewInt(3).ToObject()}, 242 {f: "max", args: wrapArgs("bar", "foo"), want: NewStr("foo").ToObject()}, 243 {f: "max", args: wrapArgs(newTestList(2, 3, 1)), want: NewInt(3).ToObject()}, 244 {f: "max", args: wrapArgs(newTestList("bar", "foo")), want: NewStr("foo").ToObject()}, 245 {f: "max", args: wrapArgs(2, 3, 1), want: NewInt(3).ToObject()}, 246 {f: "max", args: wrapArgs("bar", "foo"), want: NewStr("foo").ToObject()}, 247 {f: "max", args: wrapArgs(newTestList(2, 3, 1)), want: NewInt(3).ToObject()}, 248 {f: "max", args: wrapArgs(newTestList("bar", "foo")), want: NewStr("foo").ToObject()}, 249 {f: "max", args: wrapArgs(2, 3, 1), kwargs: wrapKWArgs("key", neg), want: NewInt(1).ToObject()}, 250 {f: "max", args: wrapArgs(1, 2, 3), kwargs: wrapKWArgs("key", neg), want: NewInt(1).ToObject()}, 251 {f: "max", args: wrapArgs(newTestList(2, 3, 1)), kwargs: wrapKWArgs("key", neg), want: NewInt(1).ToObject()}, 252 {f: "max", args: wrapArgs(newTestList(1, 2, 3)), kwargs: wrapKWArgs("key", neg), want: NewInt(1).ToObject()}, 253 {f: "max", args: wrapArgs(2, 3, 1), kwargs: wrapKWArgs("key", neg), want: NewInt(1).ToObject()}, 254 {f: "max", args: wrapArgs(1, 2, 3), kwargs: wrapKWArgs("key", neg), want: NewInt(1).ToObject()}, 255 {f: "max", args: wrapArgs(newTestList(2, 3, 1)), kwargs: wrapKWArgs("key", neg), want: NewInt(1).ToObject()}, 256 {f: "max", args: wrapArgs(newTestList(1, 2, 3)), kwargs: wrapKWArgs("key", neg), want: NewInt(1).ToObject()}, 257 {f: "max", args: wrapArgs(newTestList("foo")), want: NewStr("foo").ToObject()}, 258 {f: "max", args: wrapArgs(1), wantExc: mustCreateException(TypeErrorType, "'int' object is not iterable")}, 259 {f: "max", args: wrapArgs(), wantExc: mustCreateException(TypeErrorType, "'max' requires 1 arguments")}, 260 {f: "max", args: wrapArgs(newTestList()), wantExc: mustCreateException(ValueErrorType, "max() arg is an empty sequence")}, 261 {f: "max", args: wrapArgs(1, 2), kwargs: wrapKWArgs("key", raiseKey), wantExc: mustCreateException(RuntimeErrorType, "foo")}, 262 {f: "min", args: wrapArgs(2, 3, 1), want: NewInt(1).ToObject()}, 263 {f: "min", args: wrapArgs("bar", "foo"), want: NewStr("bar").ToObject()}, 264 {f: "min", args: wrapArgs(newTestList(2, 3, 1)), want: NewInt(1).ToObject()}, 265 {f: "min", args: wrapArgs(newTestList("bar", "foo")), want: NewStr("bar").ToObject()}, 266 {f: "min", args: wrapArgs(2, 3, 1), want: NewInt(1).ToObject()}, 267 {f: "min", args: wrapArgs("bar", "foo"), want: NewStr("bar").ToObject()}, 268 {f: "min", args: wrapArgs(newTestList(2, 3, 1)), want: NewInt(1).ToObject()}, 269 {f: "min", args: wrapArgs(newTestList("bar", "foo")), want: NewStr("bar").ToObject()}, 270 {f: "min", args: wrapArgs(2, 3, 1), kwargs: wrapKWArgs("key", neg), want: NewInt(3).ToObject()}, 271 {f: "min", args: wrapArgs(1, 2, 3), kwargs: wrapKWArgs("key", neg), want: NewInt(3).ToObject()}, 272 {f: "min", args: wrapArgs(newTestList(2, 3, 1)), kwargs: wrapKWArgs("key", neg), want: NewInt(3).ToObject()}, 273 {f: "min", args: wrapArgs(newTestList(1, 2, 3)), kwargs: wrapKWArgs("key", neg), want: NewInt(3).ToObject()}, 274 {f: "min", args: wrapArgs(2, 3, 1), kwargs: wrapKWArgs("key", neg), want: NewInt(3).ToObject()}, 275 {f: "min", args: wrapArgs(1, 2, 3), kwargs: wrapKWArgs("key", neg), want: NewInt(3).ToObject()}, 276 {f: "min", args: wrapArgs(newTestList(2, 3, 1)), kwargs: wrapKWArgs("key", neg), want: NewInt(3).ToObject()}, 277 {f: "min", args: wrapArgs(newTestList(1, 2, 3)), kwargs: wrapKWArgs("key", neg), want: NewInt(3).ToObject()}, 278 {f: "min", args: wrapArgs(newTestList("foo")), want: NewStr("foo").ToObject()}, 279 {f: "min", args: wrapArgs(1), wantExc: mustCreateException(TypeErrorType, "'int' object is not iterable")}, 280 {f: "min", args: wrapArgs(), wantExc: mustCreateException(TypeErrorType, "'min' requires 1 arguments")}, 281 {f: "min", args: wrapArgs(newTestList()), wantExc: mustCreateException(ValueErrorType, "min() arg is an empty sequence")}, 282 {f: "min", args: wrapArgs(1, 2), kwargs: wrapKWArgs("key", raiseKey), wantExc: mustCreateException(RuntimeErrorType, "foo")}, 283 {f: "oct", args: wrapArgs(077), want: NewStr("077").ToObject()}, 284 {f: "oct", args: wrapArgs(0), want: NewStr("0").ToObject()}, 285 {f: "oct", args: wrapArgs(1), want: NewStr("01").ToObject()}, 286 {f: "oct", args: wrapArgs(-1), want: NewStr("-01").ToObject()}, 287 {f: "oct", args: wrapArgs(big.NewInt(-1)), want: NewStr("-01L").ToObject()}, 288 {f: "oct", args: wrapArgs("foo"), wantExc: mustCreateException(TypeErrorType, "oct() argument can't be converted to oct")}, 289 {f: "oct", args: wrapArgs(0.1), wantExc: mustCreateException(TypeErrorType, "oct() argument can't be converted to oct")}, 290 {f: "oct", args: wrapArgs(1, 2, 3), wantExc: mustCreateException(TypeErrorType, "'oct' requires 1 arguments")}, 291 {f: "oct", args: wrapArgs(newObject(hexOctType)), want: NewStr("0octal").ToObject()}, 292 {f: "ord", args: wrapArgs("a"), want: NewInt(97).ToObject()}, 293 {f: "ord", args: wrapArgs(NewUnicode("樂")), want: NewInt(63764).ToObject()}, 294 {f: "ord", args: wrapArgs("foo"), wantExc: mustCreateException(ValueErrorType, "ord() expected a character, but string of length 3 found")}, 295 {f: "ord", args: wrapArgs(NewUnicode("волн")), wantExc: mustCreateException(ValueErrorType, "ord() expected a character, but string of length 4 found")}, 296 {f: "ord", args: wrapArgs(1, 2, 3), wantExc: mustCreateException(TypeErrorType, "'ord' requires 1 arguments")}, 297 {f: "range", args: wrapArgs(), wantExc: mustCreateException(TypeErrorType, "'__new__' of 'int' requires 3 arguments")}, 298 {f: "range", args: wrapArgs(3), want: newTestList(0, 1, 2).ToObject()}, 299 {f: "range", args: wrapArgs(10, 0), want: NewList().ToObject()}, 300 {f: "range", args: wrapArgs(-12, -23, -5), want: newTestList(-12, -17, -22).ToObject()}, 301 {f: "repr", args: wrapArgs(123), want: NewStr("123").ToObject()}, 302 {f: "repr", args: wrapArgs(NewUnicode("abc")), want: NewStr("u'abc'").ToObject()}, 303 {f: "repr", args: wrapArgs(newTestTuple("foo", "bar")), want: NewStr("('foo', 'bar')").ToObject()}, 304 {f: "repr", args: wrapArgs("a", "b", "c"), wantExc: mustCreateException(TypeErrorType, "'repr' requires 1 arguments")}, 305 {f: "round", args: wrapArgs(1234.567), want: NewFloat(1235).ToObject()}, 306 {f: "round", args: wrapArgs(1234.111), want: NewFloat(1234).ToObject()}, 307 {f: "round", args: wrapArgs(-1234.567), want: NewFloat(-1235).ToObject()}, 308 {f: "round", args: wrapArgs(-1234.111), want: NewFloat(-1234).ToObject()}, 309 {f: "round", args: wrapArgs(1234.567, newTestIndexObject(0)), want: NewFloat(1235).ToObject()}, 310 {f: "round", args: wrapArgs("foo"), wantExc: mustCreateException(TypeErrorType, "a float is required")}, 311 {f: "round", args: wrapArgs(12.5, 0), want: NewFloat(13.0).ToObject()}, 312 {f: "round", args: wrapArgs(-12.5, 0), want: NewFloat(-13.0).ToObject()}, 313 {f: "round", args: wrapArgs(12.5, 3), want: NewFloat(12.5).ToObject()}, 314 {f: "round", args: wrapArgs(1234.5, 1), want: NewFloat(1234.5).ToObject()}, 315 {f: "round", args: wrapArgs(1234.5, 1), want: NewFloat(1234.5).ToObject()}, 316 {f: "round", args: wrapArgs(1234.56, 1), want: NewFloat(1234.6).ToObject()}, 317 {f: "round", args: wrapArgs(-1234.56, 1), want: NewFloat(-1234.6).ToObject()}, 318 {f: "round", args: wrapArgs(-1234.56, -2), want: NewFloat(-1200.0).ToObject()}, 319 {f: "round", args: wrapArgs(-1234.56, -8), want: NewFloat(0.0).ToObject()}, 320 {f: "round", args: wrapArgs(63.4, -3), want: NewFloat(0.0).ToObject()}, 321 {f: "round", args: wrapArgs(63.4, -2), want: NewFloat(100.0).ToObject()}, 322 {f: "sorted", args: wrapArgs(NewList()), want: NewList().ToObject()}, 323 {f: "sorted", args: wrapArgs(newTestList("foo", "bar")), want: newTestList("bar", "foo").ToObject()}, 324 {f: "sorted", args: wrapArgs(newTestList(true, false)), want: newTestList(false, true).ToObject()}, 325 {f: "sorted", args: wrapArgs(newTestList(1, 2, 0, 3)), want: newTestRange(4).ToObject()}, 326 {f: "sorted", args: wrapArgs(newTestRange(100)), want: newTestRange(100).ToObject()}, 327 {f: "sorted", args: wrapArgs(newTestTuple(1, 2, 0, 3)), want: newTestRange(4).ToObject()}, 328 {f: "sorted", args: wrapArgs(newTestDict("foo", 1, "bar", 2)), want: newTestList("bar", "foo").ToObject()}, 329 {f: "sorted", args: wrapArgs(1), wantExc: mustCreateException(TypeErrorType, "'int' object is not iterable")}, 330 {f: "sorted", args: wrapArgs(newTestList("foo", "bar"), 2), wantExc: mustCreateException(TypeErrorType, "'sorted' requires 1 arguments")}, 331 {f: "sum", args: wrapArgs(newTestList(1, 2, 3, 4)), want: NewInt(10).ToObject()}, 332 {f: "sum", args: wrapArgs(newTestList(1, 2), 3), want: NewFloat(6).ToObject()}, 333 {f: "sum", args: wrapArgs(newTestList(2, 1.1)), want: NewFloat(3.1).ToObject()}, 334 {f: "sum", args: wrapArgs(newTestList(2, 1.1, 2)), want: NewFloat(5.1).ToObject()}, 335 {f: "sum", args: wrapArgs(newTestList(2, 1.1, 2.0)), want: NewFloat(5.1).ToObject()}, 336 {f: "sum", args: wrapArgs(newTestList(1), newObject(addType)), want: NewInt(1).ToObject()}, 337 {f: "sum", args: wrapArgs(newTestList(newObject(addType)), newObject(addType)), want: NewInt(1).ToObject()}, 338 {f: "unichr", args: wrapArgs(0), want: NewUnicode("\x00").ToObject()}, 339 {f: "unichr", args: wrapArgs(65), want: NewStr("A").ToObject()}, 340 {f: "unichr", args: wrapArgs(0x120000), wantExc: mustCreateException(ValueErrorType, "unichr() arg not in range(0x10ffff)")}, 341 {f: "unichr", args: wrapArgs(-1), wantExc: mustCreateException(ValueErrorType, "unichr() arg not in range(0x10ffff)")}, 342 {f: "unichr", args: wrapArgs(), wantExc: mustCreateException(TypeErrorType, "'unichr' requires 1 arguments")}, 343 {f: "zip", args: wrapArgs(), want: newTestList().ToObject()}, 344 {f: "zip", args: wrapArgs(newTestTuple()), want: newTestList().ToObject()}, 345 {f: "zip", args: wrapArgs(newTestList()), want: newTestList().ToObject()}, 346 {f: "zip", args: wrapArgs(newTestList(1)), want: newTestList(newTestTuple(1).ToObject()).ToObject()}, 347 {f: "zip", args: wrapArgs(newTestList(1, 2, 3)), want: newTestList(newTestTuple(1).ToObject(), newTestTuple(2).ToObject(), newTestTuple(3).ToObject()).ToObject()}, 348 {f: "zip", args: wrapArgs(newTestRange(3)), want: newTestList(newTestTuple(0).ToObject(), newTestTuple(1).ToObject(), newTestTuple(2).ToObject()).ToObject()}, 349 {f: "zip", args: wrapArgs(newTestTuple(1, 2, 3), newTestTuple(4, 5, 6)), want: NewList(newTestTuple(1, 4).ToObject(), newTestTuple(2, 5).ToObject(), newTestTuple(3, 6).ToObject()).ToObject()}, 350 {f: "zip", args: wrapArgs(newTestTuple(1, 2, 3), newTestTuple(4, 5)), want: NewList(newTestTuple(1, 4).ToObject(), newTestTuple(2, 5).ToObject()).ToObject()}, 351 {f: "zip", args: wrapArgs(newTestTuple(1, 2), newTestTuple(4, 5, 5)), want: NewList(newTestTuple(1, 4).ToObject(), newTestTuple(2, 5).ToObject()).ToObject()}, 352 {f: "zip", args: wrapArgs(1), wantExc: mustCreateException(TypeErrorType, "'int' object is not iterable")}, 353 {f: "zip", args: wrapArgs(newTestDict("foo", 1, "bar", 2)), want: newTestList(newTestTuple("foo").ToObject(), newTestTuple("bar").ToObject()).ToObject()}, 354 } 355 for _, cas := range cases { 356 fun := mustNotRaise(Builtins.GetItemString(NewRootFrame(), cas.f)) 357 if fun == nil { 358 t.Fatalf("%s not found in builtins: %v", cas.f, Builtins) 359 } 360 testCase := invokeTestCase{args: cas.args, kwargs: cas.kwargs, want: cas.want, wantExc: cas.wantExc} 361 if err := runInvokeTestCase(fun, &testCase); err != "" { 362 t.Error(err) 363 } 364 } 365 } 366 367 func TestBuiltinGlobals(t *testing.T) { 368 f := NewRootFrame() 369 f.globals = newTestDict("foo", 1, "bar", 2, 42, None) 370 globals := mustNotRaise(Builtins.GetItemString(f, "globals")) 371 got, raised := globals.Call(f, nil, nil) 372 want := newTestDict("foo", 1, "bar", 2, 42, None).ToObject() 373 switch checkResult(got, want, raised, nil) { 374 case checkInvokeResultExceptionMismatch: 375 t.Errorf("globals() = %v, want %v", got, want) 376 case checkInvokeResultReturnValueMismatch: 377 t.Errorf("globals() raised %v, want nil", raised) 378 } 379 } 380 381 func TestEllipsisRepr(t *testing.T) { 382 cas := invokeTestCase{args: wrapArgs(Ellipsis), want: NewStr("Ellipsis").ToObject()} 383 if err := runInvokeMethodTestCase(EllipsisType, "__repr__", &cas); err != "" { 384 t.Error(err) 385 } 386 } 387 388 func TestNoneRepr(t *testing.T) { 389 cas := invokeTestCase{args: wrapArgs(None), want: NewStr("None").ToObject()} 390 if err := runInvokeMethodTestCase(NoneType, "__repr__", &cas); err != "" { 391 t.Error(err) 392 } 393 } 394 395 func TestNotImplementedRepr(t *testing.T) { 396 cas := invokeTestCase{args: wrapArgs(NotImplemented), want: NewStr("NotImplemented").ToObject()} 397 if err := runInvokeMethodTestCase(NotImplementedType, "__repr__", &cas); err != "" { 398 t.Error(err) 399 } 400 } 401 402 // captureStdout invokes a function closure which writes to stdout and captures 403 // its output as string. 404 func captureStdout(f *Frame, fn func() *BaseException) (string, *BaseException) { 405 r, w, err := os.Pipe() 406 if err != nil { 407 return "", f.RaiseType(RuntimeErrorType, fmt.Sprintf("failed to open pipe: %v", err)) 408 } 409 oldStdout := Stdout 410 Stdout = NewFileFromFD(w.Fd(), nil) 411 defer func() { 412 Stdout = oldStdout 413 }() 414 done := make(chan struct{}) 415 var raised *BaseException 416 go func() { 417 defer close(done) 418 defer w.Close() 419 raised = fn() 420 }() 421 var buf bytes.Buffer 422 if _, err := io.Copy(&buf, r); err != nil { 423 return "", f.RaiseType(RuntimeErrorType, fmt.Sprintf("failed to copy buffer: %v", err)) 424 } 425 <-done 426 if raised != nil { 427 return "", raised 428 } 429 return buf.String(), nil 430 } 431 432 // TODO(corona10): Re-enable once #282 is addressed. 433 /*func TestBuiltinPrint(t *testing.T) { 434 fun := wrapFuncForTest(func(f *Frame, args *Tuple, kwargs KWArgs) (string, *BaseException) { 435 return captureStdout(f, func() *BaseException { 436 _, raised := builtinPrint(NewRootFrame(), args.elems, kwargs) 437 return raised 438 }) 439 }) 440 cases := []invokeTestCase{ 441 {args: wrapArgs(NewTuple(), wrapKWArgs()), want: NewStr("\n").ToObject()}, 442 {args: wrapArgs(newTestTuple("abc"), wrapKWArgs()), want: NewStr("abc\n").ToObject()}, 443 {args: wrapArgs(newTestTuple("abc", 123), wrapKWArgs()), want: NewStr("abc 123\n").ToObject()}, 444 {args: wrapArgs(newTestTuple("abc", 123), wrapKWArgs("sep", "")), want: NewStr("abc123\n").ToObject()}, 445 {args: wrapArgs(newTestTuple("abc", 123), wrapKWArgs("end", "")), want: NewStr("abc 123").ToObject()}, 446 {args: wrapArgs(newTestTuple("abc", 123), wrapKWArgs("sep", "XX", "end", "--")), want: NewStr("abcXX123--").ToObject()}, 447 } 448 for _, cas := range cases { 449 if err := runInvokeTestCase(fun, &cas); err != "" { 450 t.Error(err) 451 } 452 } 453 }*/ 454 455 func TestBuiltinSetAttr(t *testing.T) { 456 setattr := mustNotRaise(Builtins.GetItemString(NewRootFrame(), "setattr")) 457 fooType := newTestClass("Foo", []*Type{ObjectType}, newStringDict(map[string]*Object{})) 458 foo := newObject(fooType) 459 fun := wrapFuncForTest(func(f *Frame, args ...*Object) (*Object, *BaseException) { 460 result, raised := setattr.Call(f, args, nil) 461 if raised != nil { 462 return nil, raised 463 } 464 val, raised := GetAttr(f, args[0], toStrUnsafe(args[1]), nil) 465 if raised != nil { 466 return nil, raised 467 } 468 return newTestTuple(result, val).ToObject(), nil 469 }) 470 cases := []invokeTestCase{ 471 {args: wrapArgs(foo), wantExc: mustCreateException(TypeErrorType, "'setattr' requires 3 arguments")}, 472 {args: wrapArgs(newObject(fooType), "foo", "bar"), want: newTestTuple(None, "bar").ToObject()}, 473 {args: wrapArgs(newObject(fooType), "foo", 123), want: newTestTuple(None, 123).ToObject()}, 474 {args: wrapArgs(foo, "foo"), wantExc: mustCreateException(TypeErrorType, "'setattr' requires 3 arguments")}, 475 {args: wrapArgs(foo, "foo", 123, None), wantExc: mustCreateException(TypeErrorType, "'setattr' requires 3 arguments")}, 476 {args: wrapArgs(foo, 123, 123), wantExc: mustCreateException(TypeErrorType, "'setattr' requires a 'str' object but received a \"int\"")}, 477 } 478 for _, cas := range cases { 479 if err := runInvokeTestCase(fun, &cas); err != "" { 480 t.Error(err) 481 } 482 } 483 } 484 485 // TODO(corona10): Re-enable once #282 is addressed. 486 /*func TestRawInput(t *testing.T) { 487 fun := wrapFuncForTest(func(f *Frame, s string, args ...*Object) (*Object, *BaseException) { 488 // Create a fake Stdin for input test. 489 stdinFile, w, err := os.Pipe() 490 if err != nil { 491 return nil, f.RaiseType(RuntimeErrorType, fmt.Sprintf("failed to open pipe: %v", err)) 492 } 493 494 go func() { 495 w.Write([]byte(s)) 496 w.Close() 497 }() 498 499 oldStdin := Stdin 500 Stdin = NewFileFromFD(stdinFile.Fd(), nil) 501 defer func() { 502 Stdin = oldStdin 503 stdinFile.Close() 504 }() 505 506 var input *Object 507 output, raised := captureStdout(f, func() *BaseException { 508 in, raised := builtinRawInput(f, args, nil) 509 input = in 510 return raised 511 }) 512 513 if raised != nil { 514 return nil, raised 515 } 516 517 return newTestTuple(input, output).ToObject(), nil 518 }) 519 520 cases := []invokeTestCase{ 521 {args: wrapArgs("HelloGrumpy\n", ""), want: newTestTuple("HelloGrumpy", "").ToObject()}, 522 {args: wrapArgs("HelloGrumpy\n", "ShouldBeShown\nShouldBeShown\t"), want: newTestTuple("HelloGrumpy", "ShouldBeShown\nShouldBeShown\t").ToObject()}, 523 {args: wrapArgs("HelloGrumpy\n", 5, 4), wantExc: mustCreateException(TypeErrorType, "[raw_]input expcted at most 1 arguments, got 2")}, 524 {args: wrapArgs("HelloGrumpy\nHelloGrumpy\n", ""), want: newTestTuple("HelloGrumpy", "").ToObject()}, 525 {args: wrapArgs("HelloGrumpy\nHelloGrumpy\n", "ShouldBeShown\nShouldBeShown\t"), want: newTestTuple("HelloGrumpy", "ShouldBeShown\nShouldBeShown\t").ToObject()}, 526 {args: wrapArgs("HelloGrumpy\nHelloGrumpy\n", 5, 4), wantExc: mustCreateException(TypeErrorType, "[raw_]input expcted at most 1 arguments, got 2")}, 527 {args: wrapArgs("", ""), wantExc: mustCreateException(EOFErrorType, "EOF when reading a line")}, 528 {args: wrapArgs("", "ShouldBeShown\nShouldBeShown\t"), wantExc: mustCreateException(EOFErrorType, "EOF when reading a line")}, 529 {args: wrapArgs("", 5, 4), wantExc: mustCreateException(TypeErrorType, "[raw_]input expcted at most 1 arguments, got 2")}, 530 } 531 532 for _, cas := range cases { 533 if err := runInvokeTestCase(fun, &cas); err != "" { 534 t.Error(err) 535 } 536 } 537 538 }*/ 539 540 func newTestIndexObject(index int) *Object { 541 indexType := newTestClass("Index", []*Type{ObjectType}, newStringDict(map[string]*Object{ 542 "__index__": newBuiltinFunction("__index__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) { 543 return NewInt(index).ToObject(), nil 544 }).ToObject(), 545 })) 546 return newObject(indexType) 547 }