github.com/google/grumpy@v0.0.0-20171122020858-3ec87959189c/runtime/list_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 "math/big" 19 "reflect" 20 "testing" 21 ) 22 23 func TestNewList(t *testing.T) { 24 cases := [][]*Object{ 25 nil, 26 []*Object{newObject(ObjectType)}, 27 []*Object{newObject(ObjectType), newObject(ObjectType)}, 28 } 29 for _, args := range cases { 30 l := NewList(args...) 31 if !reflect.DeepEqual(l.elems, args) { 32 t.Errorf("NewList(%v) = %v, want %v", args, l.elems, args) 33 } 34 } 35 } 36 37 func TestListBinaryOps(t *testing.T) { 38 cases := []struct { 39 fun func(f *Frame, v, w *Object) (*Object, *BaseException) 40 v, w *Object 41 want *Object 42 wantExc *BaseException 43 }{ 44 {Add, newTestList(3).ToObject(), newTestList("foo").ToObject(), newTestList(3, "foo").ToObject(), nil}, 45 {Add, NewList(None).ToObject(), NewList().ToObject(), NewList(None).ToObject(), nil}, 46 {Add, NewList().ToObject(), newObject(ObjectType), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for +: 'list' and 'object'")}, 47 {Add, None, NewList().ToObject(), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for +: 'NoneType' and 'list'")}, 48 {Mul, NewList().ToObject(), NewInt(10).ToObject(), NewList().ToObject(), nil}, 49 {Mul, newTestList("baz").ToObject(), NewInt(-2).ToObject(), NewList().ToObject(), nil}, 50 {Mul, NewList(None, None).ToObject(), NewInt(0).ToObject(), NewList().ToObject(), nil}, 51 {Mul, newTestList(1, "bar").ToObject(), NewInt(2).ToObject(), newTestList(1, "bar", 1, "bar").ToObject(), nil}, 52 {Mul, NewInt(1).ToObject(), newTestList(1, "bar").ToObject(), newTestList(1, "bar").ToObject(), nil}, 53 {Mul, newObject(ObjectType), NewList(newObject(ObjectType)).ToObject(), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for *: 'object' and 'list'")}, 54 {Mul, NewList(newObject(ObjectType)).ToObject(), NewList().ToObject(), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for *: 'list' and 'list'")}, 55 {Mul, NewList(None, None).ToObject(), NewInt(MaxInt).ToObject(), nil, mustCreateException(OverflowErrorType, "result too large")}, 56 } 57 for _, cas := range cases { 58 testCase := invokeTestCase{args: wrapArgs(cas.v, cas.w), want: cas.want, wantExc: cas.wantExc} 59 if err := runInvokeTestCase(wrapFuncForTest(cas.fun), &testCase); err != "" { 60 t.Error(err) 61 } 62 } 63 } 64 65 func TestListCompare(t *testing.T) { 66 o := newObject(ObjectType) 67 cases := []invokeTestCase{ 68 {args: wrapArgs(NewList(), NewList()), want: compareAllResultEq}, 69 {args: wrapArgs(newTestList("foo", o), newTestList("foo", o)), want: compareAllResultEq}, 70 {args: wrapArgs(newTestList(4), newTestList(3, 0)), want: compareAllResultGT}, 71 {args: wrapArgs(newTestList(4), newTestList(4, 3, 0)), want: compareAllResultLT}, 72 {args: wrapArgs(NewList(o), NewList()), want: compareAllResultGT}, 73 {args: wrapArgs(NewList(o), newTestList("foo")), want: compareAllResultLT}, 74 } 75 for _, cas := range cases { 76 if err := runInvokeTestCase(compareAll, &cas); err != "" { 77 t.Error(err) 78 } 79 } 80 } 81 82 func TestListCount(t *testing.T) { 83 cases := []invokeTestCase{ 84 {args: wrapArgs(NewList(), NewInt(1)), want: NewInt(0).ToObject()}, 85 {args: wrapArgs(NewList(None, None, None), None), want: NewInt(3).ToObject()}, 86 {args: wrapArgs(newTestList()), wantExc: mustCreateException(TypeErrorType, "'count' of 'list' requires 2 arguments")}, 87 } 88 for _, cas := range cases { 89 if err := runInvokeMethodTestCase(ListType, "count", &cas); err != "" { 90 t.Error(err) 91 } 92 } 93 } 94 95 func TestListDelItem(t *testing.T) { 96 badIndexType := newTestClass("badIndex", []*Type{ObjectType}, newStringDict(map[string]*Object{ 97 "__index__": newBuiltinFunction("__index__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) { 98 return nil, f.RaiseType(ValueErrorType, "wut") 99 }).ToObject(), 100 })) 101 delItem := mustNotRaise(GetAttr(NewRootFrame(), ListType.ToObject(), NewStr("__delitem__"), nil)) 102 fun := wrapFuncForTest(func(f *Frame, l *List, key *Object) (*Object, *BaseException) { 103 _, raised := delItem.Call(f, wrapArgs(l, key), nil) 104 if raised != nil { 105 return nil, raised 106 } 107 return l.ToObject(), nil 108 }) 109 cases := []invokeTestCase{ 110 {args: wrapArgs(newTestRange(3), 0), want: newTestList(1, 2).ToObject()}, 111 {args: wrapArgs(newTestRange(3), 2), want: newTestList(0, 1).ToObject()}, 112 {args: wrapArgs(NewList(), 101), wantExc: mustCreateException(IndexErrorType, "index out of range")}, 113 {args: wrapArgs(NewList(), newTestSlice(50, 100)), want: NewList().ToObject()}, 114 {args: wrapArgs(newTestList(1, 2, 3, 4, 5), newTestSlice(1, 3, None)), want: newTestList(1, 4, 5).ToObject()}, 115 {args: wrapArgs(newTestList(1, 2, 3, 4, 5), newTestSlice(1, None, 2)), want: newTestList(1, 3, 5).ToObject()}, 116 {args: wrapArgs(newTestList(1, 2, 3, 4, 5), newTestSlice(big.NewInt(1), None, 2)), want: newTestList(1, 3, 5).ToObject()}, 117 {args: wrapArgs(newTestList(1, 2, 3, 4, 5), newTestSlice(1, big.NewInt(5), 2)), want: newTestList(1, 3, 5).ToObject()}, 118 {args: wrapArgs(newTestList(1, 2, 3, 4, 5), newTestSlice(1, None, big.NewInt(2))), want: newTestList(1, 3, 5).ToObject()}, 119 {args: wrapArgs(newTestList(1, 2, 3, 4, 5), newTestSlice(1.0, 3, None)), wantExc: mustCreateException(TypeErrorType, errBadSliceIndex)}, 120 {args: wrapArgs(newTestList(1, 2, 3, 4, 5), newTestSlice(None, None, 4)), want: newTestList(2, 3, 4).ToObject()}, 121 {args: wrapArgs(newTestRange(10), newTestSlice(1, 8, 3)), want: newTestList(0, 2, 3, 5, 6, 8, 9).ToObject()}, 122 {args: wrapArgs(newTestList(1, 2, 3), newTestSlice(1, None, 0)), wantExc: mustCreateException(ValueErrorType, "slice step cannot be zero")}, 123 {args: wrapArgs(newTestList(true), None), wantExc: mustCreateException(TypeErrorType, "list indices must be integers, not NoneType")}, 124 {args: wrapArgs(newTestList(true), newObject(badIndexType)), wantExc: mustCreateException(ValueErrorType, "wut")}, 125 } 126 for _, cas := range cases { 127 if err := runInvokeTestCase(fun, &cas); err != "" { 128 t.Error(err) 129 } 130 } 131 } 132 133 func TestListIndex(t *testing.T) { 134 intIndexType := newTestClass("IntIndex", []*Type{ObjectType}, newStringDict(map[string]*Object{ 135 "__index__": newBuiltinFunction("__index__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) { 136 return NewInt(0).ToObject(), nil 137 }).ToObject(), 138 })) 139 cases := []invokeTestCase{ 140 // {args: wrapArgs(newTestList(), 1, "foo"), wantExc: mustCreateException(TypeErrorType, "slice indices must be integers or None or have an __index__ method")}, 141 {args: wrapArgs(newTestList(10, 20, 30), 20), want: NewInt(1).ToObject()}, 142 {args: wrapArgs(newTestList(10, 20, 30), 20, newObject(intIndexType)), want: NewInt(1).ToObject()}, 143 {args: wrapArgs(newTestList(0, "foo", "bar"), "foo"), want: NewInt(1).ToObject()}, 144 {args: wrapArgs(newTestList(0, 1, 2, 3, 4), 3, 3), want: NewInt(3).ToObject()}, 145 {args: wrapArgs(newTestList(0, 2.0, 2, 3, 4, 2, 1, "foo"), 3, 3), want: NewInt(3).ToObject()}, 146 {args: wrapArgs(newTestList(0, 1, 2, 3, 4), 3, 4), wantExc: mustCreateException(ValueErrorType, "3 is not in list")}, 147 {args: wrapArgs(newTestList(0, 1, 2, 3, 4), 3, 0, 4), want: NewInt(3).ToObject()}, 148 {args: wrapArgs(newTestList(0, 1, 2, 3, 4), 3, 0, 3), wantExc: mustCreateException(ValueErrorType, "3 is not in list")}, 149 {args: wrapArgs(newTestList(0, 1, 2, 3, 4), 3, -2), want: NewInt(3).ToObject()}, 150 {args: wrapArgs(newTestList(0, 1, 2, 3, 4), 3, -1), wantExc: mustCreateException(ValueErrorType, "3 is not in list")}, 151 {args: wrapArgs(newTestList(0, 1, 2, 3, 4), 3, 0, -1), want: NewInt(3).ToObject()}, 152 {args: wrapArgs(newTestList(0, 1, 2, 3, 4), 3, 0, -2), wantExc: mustCreateException(ValueErrorType, "3 is not in list")}, 153 {args: wrapArgs(newTestList(0, 1, 2, 3, 4), 3, 0, 999), want: NewInt(3).ToObject()}, 154 {args: wrapArgs(newTestList(0, 1, 2, 3, 4), "foo", 0, 999), wantExc: mustCreateException(ValueErrorType, "'foo' is not in list")}, 155 {args: wrapArgs(newTestList(0, 1, 2, 3, 4), 3, 999), wantExc: mustCreateException(ValueErrorType, "3 is not in list")}, 156 {args: wrapArgs(newTestList(0, 1, 2, 3, 4), 3, 5, 0), wantExc: mustCreateException(ValueErrorType, "3 is not in list")}, 157 } 158 for _, cas := range cases { 159 if err := runInvokeMethodTestCase(ListType, "index", &cas); err != "" { 160 t.Error(err) 161 } 162 } 163 } 164 165 func TestListRemove(t *testing.T) { 166 fun := newBuiltinFunction("TestListRemove", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) { 167 rem, raised := GetAttr(f, ListType.ToObject(), NewStr("remove"), nil) 168 if raised != nil { 169 return nil, raised 170 } 171 if _, raised := rem.Call(f, args, nil); raised != nil { 172 return nil, raised 173 } 174 return args[0], nil 175 }).ToObject() 176 cases := []invokeTestCase{ 177 {args: wrapArgs(newTestList(1, 2, 3), 2), want: newTestList(1, 3).ToObject()}, 178 {args: wrapArgs(newTestList(1, 2, 3, 2, 1), 2), want: newTestList(1, 3, 2, 1).ToObject()}, 179 {args: wrapArgs(NewList()), wantExc: mustCreateException(TypeErrorType, "'remove' of 'list' requires 2 arguments")}, 180 {args: wrapArgs(NewList(), 1), wantExc: mustCreateException(ValueErrorType, "list.remove(x): x not in list")}, 181 } 182 for _, cas := range cases { 183 if err := runInvokeTestCase(fun, &cas); err != "" { 184 t.Error(err) 185 } 186 } 187 } 188 189 func BenchmarkListContains(b *testing.B) { 190 b.Run("false-3", func(b *testing.B) { 191 t := newTestList("foo", 42, "bar").ToObject() 192 a := wrapArgs(1)[0] 193 f := NewRootFrame() 194 b.ResetTimer() 195 for i := 0; i < b.N; i++ { 196 Contains(f, t, a) 197 } 198 }) 199 200 b.Run("false-10", func(b *testing.B) { 201 t := newTestList("foo", 42, "bar", "foo", 42, "bar", "foo", 42, "bar", "baz").ToObject() 202 a := wrapArgs(1)[0] 203 f := NewRootFrame() 204 b.ResetTimer() 205 for i := 0; i < b.N; i++ { 206 Contains(f, t, a) 207 } 208 }) 209 210 b.Run("true-3.1", func(b *testing.B) { 211 t := newTestList("foo", 42, "bar").ToObject() 212 a := wrapArgs("foo")[0] 213 f := NewRootFrame() 214 b.ResetTimer() 215 for i := 0; i < b.N; i++ { 216 Contains(f, t, a) 217 } 218 }) 219 220 b.Run("true-3.3", func(b *testing.B) { 221 t := newTestList("foo", 42, "bar").ToObject() 222 a := wrapArgs("bar")[0] 223 f := NewRootFrame() 224 b.ResetTimer() 225 for i := 0; i < b.N; i++ { 226 Contains(f, t, a) 227 } 228 }) 229 230 b.Run("true-10.10", func(b *testing.B) { 231 t := newTestList("foo", 42, "bar", "foo", 42, "bar", "foo", 42, "bar", "baz").ToObject() 232 a := wrapArgs("baz")[0] 233 f := NewRootFrame() 234 b.ResetTimer() 235 for i := 0; i < b.N; i++ { 236 Contains(f, t, a) 237 } 238 }) 239 } 240 241 func TestListGetItem(t *testing.T) { 242 cases := []invokeTestCase{ 243 {args: wrapArgs(newTestRange(20), 0), want: NewInt(0).ToObject()}, 244 {args: wrapArgs(newTestRange(20), 19), want: NewInt(19).ToObject()}, 245 {args: wrapArgs(NewList(), 101), wantExc: mustCreateException(IndexErrorType, "index out of range")}, 246 {args: wrapArgs(NewList(), newTestSlice(50, 100)), want: NewList().ToObject()}, 247 {args: wrapArgs(newTestList(1, 2, 3, 4, 5), newTestSlice(1, 3, None)), want: newTestList(2, 3).ToObject()}, 248 {args: wrapArgs(newTestList(1, 2, 3, 4, 5), newTestSlice(1, None, 2)), want: newTestList(2, 4).ToObject()}, 249 {args: wrapArgs(newTestList(1, 2, 3, 4, 5), newTestSlice(big.NewInt(1), None, 2)), want: newTestList(2, 4).ToObject()}, 250 {args: wrapArgs(newTestList(1, 2, 3, 4, 5), newTestSlice(1, big.NewInt(5), 2)), want: newTestList(2, 4).ToObject()}, 251 {args: wrapArgs(newTestList(1, 2, 3, 4, 5), newTestSlice(1, None, big.NewInt(2))), want: newTestList(2, 4).ToObject()}, 252 {args: wrapArgs(newTestList(1, 2, 3, 4, 5), newTestSlice(1.0, 3, None)), wantExc: mustCreateException(TypeErrorType, errBadSliceIndex)}, 253 {args: wrapArgs(newTestList(1, 2, 3), newTestSlice(1, None, 0)), wantExc: mustCreateException(ValueErrorType, "slice step cannot be zero")}, 254 {args: wrapArgs(newTestList(true), None), wantExc: mustCreateException(TypeErrorType, "list indices must be integers, not NoneType")}, 255 } 256 for _, cas := range cases { 257 if err := runInvokeMethodTestCase(ListType, "__getitem__", &cas); err != "" { 258 t.Error(err) 259 } 260 } 261 } 262 263 func TestListInplaceOps(t *testing.T) { 264 cases := []struct { 265 fun func(f *Frame, v, w *Object) (*Object, *BaseException) 266 v, w *Object 267 want *Object 268 wantExc *BaseException 269 }{ 270 {IAdd, newTestList(3).ToObject(), newTestList("foo").ToObject(), newTestList(3, "foo").ToObject(), nil}, 271 {IAdd, NewList(None).ToObject(), NewList().ToObject(), NewList(None).ToObject(), nil}, 272 {IAdd, NewList().ToObject(), newObject(ObjectType), nil, mustCreateException(TypeErrorType, "'object' object is not iterable")}, 273 {IMul, NewList().ToObject(), NewInt(10).ToObject(), NewList().ToObject(), nil}, 274 {IMul, newTestList("baz").ToObject(), NewInt(-2).ToObject(), NewList().ToObject(), nil}, 275 {IMul, NewList().ToObject(), None, nil, mustCreateException(TypeErrorType, "can't multiply sequence by non-int of type 'NoneType'")}, 276 } 277 for _, cas := range cases { 278 switch got, result := checkInvokeResult(wrapFuncForTest(cas.fun), []*Object{cas.v, cas.w}, cas.want, cas.wantExc); result { 279 case checkInvokeResultExceptionMismatch: 280 t.Errorf("%s(%v, %v) raised %v, want %v", getFuncName(cas.fun), cas.v, cas.w, got, cas.wantExc) 281 case checkInvokeResultReturnValueMismatch: 282 t.Errorf("%s(%v, %v) = %v, want %v", getFuncName(cas.fun), cas.v, cas.w, got, cas.want) 283 default: 284 if got != nil && got != cas.v { 285 t.Errorf("%s(%v, %v) did not return identity", getFuncName(cas.fun), cas.v, cas.w) 286 } 287 } 288 } 289 } 290 291 func TestListIsTrue(t *testing.T) { 292 cases := []invokeTestCase{ 293 {args: wrapArgs(NewList()), want: False.ToObject()}, 294 {args: wrapArgs(newTestList("foo", None)), want: True.ToObject()}, 295 } 296 for _, cas := range cases { 297 if err := runInvokeTestCase(wrapFuncForTest(IsTrue), &cas); err != "" { 298 t.Error(err) 299 } 300 } 301 } 302 303 func TestListAppend(t *testing.T) { 304 fun := newBuiltinFunction("TestListAppend", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) { 305 if raised := checkFunctionArgs(f, "TestListAppend", args, ListType, ObjectType); raised != nil { 306 return nil, raised 307 } 308 app, raised := GetAttr(f, ListType.ToObject(), NewStr("append"), nil) 309 if raised != nil { 310 return nil, raised 311 } 312 if _, raised := app.Call(f, args, nil); raised != nil { 313 return nil, raised 314 } 315 return args[0], nil 316 }).ToObject() 317 cases := []invokeTestCase{ 318 {args: wrapArgs(NewList(), None), want: NewList(None).ToObject()}, 319 {args: wrapArgs(NewList(None), 42), want: newTestList(None, 42).ToObject()}, 320 {args: wrapArgs(newTestList(None, 42), "foo"), want: newTestList(None, 42, "foo").ToObject()}, 321 {args: wrapArgs(newTestRange(100), 100), want: newTestRange(101).ToObject()}, 322 } 323 for _, cas := range cases { 324 if err := runInvokeTestCase(fun, &cas); err != "" { 325 t.Error(err) 326 } 327 } 328 } 329 330 func TestListExtend(t *testing.T) { 331 extend := mustNotRaise(GetAttr(NewRootFrame(), ListType.ToObject(), NewStr("extend"), nil)) 332 fun := newBuiltinFunction("TestListExtend", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) { 333 if _, raised := extend.Call(f, args, nil); raised != nil { 334 return nil, raised 335 } 336 return args[0], nil 337 }).ToObject() 338 cases := []invokeTestCase{ 339 {args: wrapArgs(newTestList(), newTestTuple()), want: newTestList().ToObject()}, 340 {args: wrapArgs(newTestList(), newTestList()), want: newTestList().ToObject()}, 341 {args: wrapArgs(newTestList(3), newTestList("foo")), want: newTestList(3, "foo").ToObject()}, 342 {args: wrapArgs(newTestList(), newTestList("foo")), want: newTestList("foo").ToObject()}, 343 {args: wrapArgs(newTestList(3), newTestList()), want: newTestList(3).ToObject()}, 344 {args: wrapArgs(NewStr(""), newTestList()), wantExc: mustCreateException(TypeErrorType, "unbound method extend() must be called with list instance as first argument (got str instance instead)")}, 345 {args: wrapArgs(None, None), wantExc: mustCreateException(TypeErrorType, "unbound method extend() must be called with list instance as first argument (got NoneType instance instead)")}, 346 {args: wrapArgs(newTestList(3), None), wantExc: mustCreateException(TypeErrorType, "'NoneType' object is not iterable")}, 347 {args: wrapArgs(newTestRange(5), newTestList(3)), want: newTestList(0, 1, 2, 3, 4, 3).ToObject()}, 348 {args: wrapArgs(newTestRange(5), newTestList(3)), want: newTestList(0, 1, 2, 3, 4, 3).ToObject()}, 349 {args: wrapArgs(newTestTuple(1, 2, 3), newTestList(3)), wantExc: mustCreateException(TypeErrorType, "unbound method extend() must be called with list instance as first argument (got tuple instance instead)")}, 350 {args: wrapArgs(newTestList(4), newTestTuple(1, 2, 3)), want: newTestList(4, 1, 2, 3).ToObject()}, 351 {args: wrapArgs(newTestList()), wantExc: mustCreateException(TypeErrorType, "extend() takes exactly one argument (1 given)")}, 352 {args: wrapArgs(newTestList(), newTestTuple(), newTestTuple()), wantExc: mustCreateException(TypeErrorType, "extend() takes exactly one argument (3 given)")}, 353 } 354 for _, cas := range cases { 355 if err := runInvokeTestCase(fun, &cas); err != "" { 356 t.Error(err) 357 } 358 } 359 } 360 361 func TestListLen(t *testing.T) { 362 cases := []invokeTestCase{ 363 {args: wrapArgs(NewList()), want: NewInt(0).ToObject()}, 364 {args: wrapArgs(NewList(None, None, None)), want: NewInt(3).ToObject()}, 365 } 366 for _, cas := range cases { 367 if err := runInvokeMethodTestCase(ListType, "__len__", &cas); err != "" { 368 t.Error(err) 369 } 370 } 371 } 372 373 func TestListNew(t *testing.T) { 374 cases := []invokeTestCase{ 375 {want: NewList().ToObject()}, 376 {args: wrapArgs(newTestTuple(1, 2, 3)), want: newTestList(1, 2, 3).ToObject()}, 377 {args: wrapArgs(newTestDict(1, "foo", "bar", None)), want: newTestList(1, "bar").ToObject()}, 378 {args: wrapArgs(42), wantExc: mustCreateException(TypeErrorType, "'int' object is not iterable")}, 379 } 380 for _, cas := range cases { 381 if err := runInvokeTestCase(ListType.ToObject(), &cas); err != "" { 382 t.Error(err) 383 } 384 } 385 } 386 387 func TestListReverse(t *testing.T) { 388 reverse := mustNotRaise(GetAttr(NewRootFrame(), ListType.ToObject(), NewStr("reverse"), nil)) 389 fun := wrapFuncForTest(func(f *Frame, o *Object, args ...*Object) (*Object, *BaseException) { 390 _, raised := reverse.Call(f, append(Args{o}, args...), nil) 391 if raised != nil { 392 return nil, raised 393 } 394 return o, nil 395 }) 396 cases := []invokeTestCase{ 397 {args: wrapArgs(NewList()), want: NewList().ToObject()}, 398 {args: wrapArgs(newTestList(1, 2, 3)), want: newTestList(3, 2, 1).ToObject()}, 399 {args: wrapArgs(NewList(), 123), wantExc: mustCreateException(TypeErrorType, "'reverse' of 'list' requires 1 arguments")}, 400 } 401 for _, cas := range cases { 402 if err := runInvokeTestCase(fun, &cas); err != "" { 403 t.Error(err) 404 } 405 } 406 } 407 408 func TestListStrRepr(t *testing.T) { 409 recursiveList := newTestList("foo").ToObject() 410 listAppend(NewRootFrame(), []*Object{recursiveList, recursiveList}, nil) 411 cases := []invokeTestCase{ 412 {args: wrapArgs(NewList()), want: NewStr("[]").ToObject()}, 413 {args: wrapArgs(newTestList("foo")), want: NewStr("['foo']").ToObject()}, 414 {args: wrapArgs(newTestList(TupleType, ExceptionType)), want: NewStr("[<type 'tuple'>, <type 'Exception'>]").ToObject()}, 415 {args: wrapArgs(recursiveList), want: NewStr("['foo', [...]]").ToObject()}, 416 } 417 for _, cas := range cases { 418 if err := runInvokeTestCase(wrapFuncForTest(ToStr), &cas); err != "" { 419 t.Error(err) 420 } 421 if err := runInvokeTestCase(wrapFuncForTest(Repr), &cas); err != "" { 422 t.Error(err) 423 } 424 } 425 } 426 427 func TestListInsert(t *testing.T) { 428 fun := wrapFuncForTest(func(f *Frame, l *List, args ...*Object) (*Object, *BaseException) { 429 insert, raised := GetAttr(NewRootFrame(), l.ToObject(), NewStr("insert"), nil) 430 if raised != nil { 431 return nil, raised 432 } 433 if _, raised := insert.Call(f, args, nil); raised != nil { 434 return nil, raised 435 } 436 return l.ToObject(), nil 437 }) 438 cases := []invokeTestCase{ 439 {args: wrapArgs(NewList(), 0, None), want: NewList(None).ToObject()}, 440 {args: wrapArgs(newTestList("bar"), -100, "foo"), want: newTestList("foo", "bar").ToObject()}, 441 {args: wrapArgs(newTestList("foo", "bar"), 101, "baz"), want: newTestList("foo", "bar", "baz").ToObject()}, 442 {args: wrapArgs(newTestList("a", "c"), 1, "b"), want: newTestList("a", "b", "c").ToObject()}, 443 {args: wrapArgs(newTestList(1, 2), 0, 0), want: newTestList(0, 1, 2).ToObject()}, 444 {args: wrapArgs(NewList()), wantExc: mustCreateException(TypeErrorType, "'insert' of 'list' requires 3 arguments")}, 445 {args: wrapArgs(NewList(), "foo", 123), wantExc: mustCreateException(TypeErrorType, "'insert' requires a 'int' object but received a 'str'")}, 446 } 447 for _, cas := range cases { 448 if err := runInvokeTestCase(fun, &cas); err != "" { 449 t.Error(err) 450 } 451 } 452 } 453 454 func TestListIter(t *testing.T) { 455 fun := newBuiltinFunction("TestListIter", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) { 456 if raised := checkFunctionArgs(f, "TestListIter", args, ListType); raised != nil { 457 return nil, raised 458 } 459 var got []*Object 460 iter, raised := Iter(f, args[0]) 461 if raised != nil { 462 return nil, raised 463 } 464 raised = seqApply(f, iter, func(elems []*Object, _ bool) *BaseException { 465 got = make([]*Object, len(elems)) 466 copy(got, elems) 467 return nil 468 }) 469 if raised != nil { 470 return nil, raised 471 } 472 return NewList(got...).ToObject(), nil 473 }).ToObject() 474 o := newObject(ObjectType) 475 cases := []invokeTestCase{ 476 {args: wrapArgs(NewList()), want: NewList().ToObject()}, 477 {args: wrapArgs(newTestList(1, o, "foo")), want: newTestList(1, o, "foo").ToObject()}, 478 } 479 for _, cas := range cases { 480 if err := runInvokeTestCase(fun, &cas); err != "" { 481 t.Error(err) 482 } 483 } 484 } 485 486 func TestListIteratorIter(t *testing.T) { 487 iter := newListIterator(NewList()) 488 cas := &invokeTestCase{args: wrapArgs(iter), want: iter} 489 if err := runInvokeMethodTestCase(listIteratorType, "__iter__", cas); err != "" { 490 t.Error(err) 491 } 492 } 493 494 func TestListPop(t *testing.T) { 495 pop := mustNotRaise(GetAttr(NewRootFrame(), ListType.ToObject(), NewStr("pop"), nil)) 496 fun := wrapFuncForTest(func(f *Frame, l *List, args ...*Object) (*Tuple, *BaseException) { 497 result, raised := pop.Call(f, append(Args{l.ToObject()}, args...), nil) 498 if raised != nil { 499 return nil, raised 500 } 501 return newTestTuple(result, l), nil 502 }) 503 cases := []invokeTestCase{ 504 {args: wrapArgs(newTestList(1)), want: newTestTuple(1, newTestList().ToObject()).ToObject()}, 505 {args: wrapArgs(newTestList(1), 0), want: newTestTuple(1, newTestList().ToObject()).ToObject()}, 506 {args: wrapArgs(newTestList(-1, 0, 1)), want: newTestTuple(1, newTestList(-1, 0).ToObject()).ToObject()}, 507 {args: wrapArgs(newTestList(-1, 0, 1), 0), want: newTestTuple(-1, newTestList(0, 1).ToObject()).ToObject()}, 508 {args: wrapArgs(newTestList(-1, 0, 1), NewLong(big.NewInt(1))), want: newTestTuple(0, newTestList(-1, 1).ToObject()).ToObject()}, 509 {args: wrapArgs(newTestList(-1, 0, 1), None), wantExc: mustCreateException(TypeErrorType, "an integer is required")}, 510 {args: wrapArgs(newTestList(-1, 0, 1), None), wantExc: mustCreateException(TypeErrorType, "an integer is required")}, 511 {args: wrapArgs(newTestList(-1, 0, 1), 3), wantExc: mustCreateException(IndexErrorType, "list index out of range")}, 512 {args: wrapArgs(newTestList()), wantExc: mustCreateException(IndexErrorType, "list index out of range")}, 513 {args: wrapArgs(newTestList(), 0), wantExc: mustCreateException(IndexErrorType, "list index out of range")}, 514 {args: wrapArgs(newTestList(), 1), wantExc: mustCreateException(IndexErrorType, "list index out of range")}, 515 } 516 for _, cas := range cases { 517 if err := runInvokeTestCase(fun, &cas); err != "" { 518 t.Error(err) 519 } 520 } 521 } 522 523 func TestListSetItem(t *testing.T) { 524 fun := newBuiltinFunction("TestListSetItem", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) { 525 // Check that there is at least one arg, but otherwise leave 526 // the validation to __setitem__. 527 if raised := checkFunctionVarArgs(f, "TestListSetItem", args, ObjectType); raised != nil { 528 return nil, raised 529 } 530 setitem, raised := GetAttr(f, args[0], NewStr("__setitem__"), nil) 531 if raised != nil { 532 return nil, raised 533 } 534 _, raised = setitem.Call(f, args[1:], nil) 535 if raised != nil { 536 return nil, raised 537 } 538 return args[0], nil 539 }).ToObject() 540 cases := []invokeTestCase{ 541 {args: wrapArgs(newTestList("foo", "bar"), 1, None), want: newTestList("foo", None).ToObject()}, 542 {args: wrapArgs(newTestList(1, 2, 3), newTestSlice(0), newTestList(0)), want: newTestList(0, 1, 2, 3).ToObject()}, 543 {args: wrapArgs(newTestList(1, 2, 3), newTestSlice(1), newTestList(4)), want: newTestList(4, 2, 3).ToObject()}, 544 {args: wrapArgs(newTestList(1, 2, 3), newTestSlice(2, None), newTestList("foo")), want: newTestList(1, 2, "foo").ToObject()}, 545 {args: wrapArgs(newTestList(1, 2, 3), newTestSlice(100, None), newTestList("foo")), want: newTestList(1, 2, 3, "foo").ToObject()}, 546 {args: wrapArgs(newTestList(1, 2, 4, 5), newTestSlice(1, None, 2), newTestTuple("foo", "bar")), want: newTestList(1, "foo", 4, "bar").ToObject()}, 547 {args: wrapArgs(newTestList(1, 2, 3), newTestSlice(None, None, 2), newTestList("foo")), wantExc: mustCreateException(ValueErrorType, "attempt to assign sequence of size 1 to extended slice of size 2")}, 548 {args: wrapArgs(newTestRange(100), newTestSlice(None, None), NewList()), want: NewList().ToObject()}, 549 {args: wrapArgs(NewList(), newTestSlice(4, 8, 0), NewList()), wantExc: mustCreateException(ValueErrorType, "slice step cannot be zero")}, 550 {args: wrapArgs(newTestList("foo", "bar"), -100, None), wantExc: mustCreateException(IndexErrorType, "index out of range")}, 551 {args: wrapArgs(NewList(), 101, None), wantExc: mustCreateException(IndexErrorType, "index out of range")}, 552 {args: wrapArgs(newTestList(true), None, false), wantExc: mustCreateException(TypeErrorType, "list indices must be integers, not NoneType")}, 553 } 554 for _, cas := range cases { 555 if err := runInvokeTestCase(fun, &cas); err != "" { 556 t.Error(err) 557 } 558 } 559 } 560 561 func TestListSort(t *testing.T) { 562 sort := mustNotRaise(GetAttr(NewRootFrame(), ListType.ToObject(), NewStr("sort"), nil)) 563 fun := newBuiltinFunction("TestListSort", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) { 564 if _, raised := sort.Call(f, args, nil); raised != nil { 565 return nil, raised 566 } 567 return args[0], nil 568 }).ToObject() 569 cases := []invokeTestCase{ 570 {args: wrapArgs(NewList()), want: NewList().ToObject()}, 571 {args: wrapArgs(newTestList("foo", "bar")), want: newTestList("bar", "foo").ToObject()}, 572 {args: wrapArgs(newTestList(true, false)), want: newTestList(false, true).ToObject()}, 573 {args: wrapArgs(newTestList(1, 2, 0, 3)), want: newTestRange(4).ToObject()}, 574 {args: wrapArgs(newTestRange(100)), want: newTestRange(100).ToObject()}, 575 {args: wrapArgs(1), wantExc: mustCreateException(TypeErrorType, "unbound method sort() must be called with list instance as first argument (got int instance instead)")}, 576 {args: wrapArgs(NewList(), 1), wantExc: mustCreateException(TypeErrorType, "'sort' of 'list' requires 1 arguments")}, 577 } 578 for _, cas := range cases { 579 if err := runInvokeTestCase(fun, &cas); err != "" { 580 t.Error(err) 581 } 582 } 583 } 584 585 func newTestRange(n int) *List { 586 elems := make([]*Object, n) 587 for i := 0; i < n; i++ { 588 elems[i] = NewInt(i).ToObject() 589 } 590 return NewList(elems...) 591 } 592 593 func newTestList(elems ...interface{}) *List { 594 listElems, raised := seqWrapEach(NewRootFrame(), elems...) 595 if raised != nil { 596 panic(raised) 597 } 598 return NewList(listElems...) 599 }