github.com/pygolin/runtime@v0.0.0-20201208210830-a62e3cd39798/generator_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 "testing" 19 ) 20 21 func TestGeneratorNext(t *testing.T) { 22 f := NewRootFrame() 23 var recursive *Object 24 recursiveFn := func(*Object) (*Object, *BaseException) { 25 next, raised := GetAttr(f, recursive, NewStr("next"), nil) 26 if raised != nil { 27 return nil, raised 28 } 29 return next.Call(f, nil, nil) 30 } 31 recursive = NewGenerator(f, recursiveFn).ToObject() 32 emptyFn := func(*Object) (*Object, *BaseException) { 33 return nil, nil 34 } 35 exhausted := NewGenerator(NewRootFrame(), emptyFn).ToObject() 36 mustNotRaise(ListType.Call(NewRootFrame(), Args{exhausted}, nil)) 37 cases := []invokeTestCase{ 38 invokeTestCase{args: wrapArgs(recursive), wantExc: mustCreateException(ValueErrorType, "generator already executing")}, 39 invokeTestCase{args: wrapArgs(exhausted), wantExc: toBaseExceptionUnsafe(mustNotRaise(StopIterationType.Call(NewRootFrame(), nil, nil)))}, 40 } 41 for _, cas := range cases { 42 if err := runInvokeMethodTestCase(GeneratorType, "next", &cas); err != "" { 43 t.Error(err) 44 } 45 } 46 } 47 48 func TestGeneratorSend(t *testing.T) { 49 emptyFn := func(*Object) (*Object, *BaseException) { 50 return nil, nil 51 } 52 cases := []invokeTestCase{ 53 invokeTestCase{args: wrapArgs(NewGenerator(NewRootFrame(), emptyFn), 123), wantExc: mustCreateException(TypeErrorType, "can't send non-None value to a just-started generator")}, 54 invokeTestCase{args: wrapArgs(NewGenerator(NewRootFrame(), emptyFn), "foo", "bar"), wantExc: mustCreateException(TypeErrorType, "'send' of 'generator' requires 2 arguments")}, 55 } 56 for _, cas := range cases { 57 if err := runInvokeMethodTestCase(GeneratorType, "send", &cas); err != "" { 58 t.Error(err) 59 } 60 } 61 } 62 63 func TestGeneratorSimple(t *testing.T) { 64 f := NewRootFrame() 65 fn := func(*Object) (*Object, *BaseException) { 66 switch f.State() { 67 case 0: 68 goto Start 69 case 1: 70 goto Yield1 71 case 2: 72 goto Yield2 73 default: 74 t.Fatalf("got invalid state %d", f.State()) 75 } 76 Start: 77 f.PushCheckpoint(1) 78 return NewStr("foo").ToObject(), nil 79 Yield1: 80 f.PushCheckpoint(2) 81 return NewStr("bar").ToObject(), nil 82 Yield2: 83 return nil, nil 84 } 85 cas := &invokeTestCase{ 86 args: wrapArgs(NewGenerator(f, fn)), 87 want: newTestList("foo", "bar").ToObject(), 88 } 89 if err := runInvokeTestCase(ListType.ToObject(), cas); err != "" { 90 t.Error(err) 91 } 92 }