github.com/arnodel/golua@v0.0.0-20230215163904-e0b5347eaaa1/runtime/thread_test.go (about) 1 package runtime 2 3 import ( 4 "reflect" 5 "testing" 6 ) 7 8 func TestThread_Resume(t *testing.T) { 9 type args struct { 10 caller *Thread 11 args []Value 12 } 13 tests := []struct { 14 name string 15 thread *Thread 16 args args 17 wantPanic interface{} 18 }{ 19 { 20 name: "caller must be running", 21 thread: &Thread{ 22 status: ThreadSuspended, 23 }, 24 args: args{ 25 caller: &Thread{ 26 status: ThreadDead, 27 }, 28 }, 29 wantPanic: "Caller of thread to resume is not running", 30 }, 31 } 32 for _, tt := range tests { 33 t.Run(tt.name, func(t *testing.T) { 34 th := tt.thread 35 gotPanic := func() (res interface{}) { 36 defer func() { res = recover() }() 37 _, _ = th.Resume(tt.args.caller, tt.args.args) 38 return 39 }() 40 if !reflect.DeepEqual(gotPanic, tt.wantPanic) { 41 t.Errorf("Thread.Resume() panic got %v, want %v", gotPanic, tt.wantPanic) 42 } 43 }) 44 } 45 } 46 47 func TestThread_Yield(t *testing.T) { 48 type args struct { 49 args []Value 50 } 51 tests := []struct { 52 name string 53 thread *Thread 54 args args 55 wantPanic interface{} 56 }{ 57 { 58 name: "Thread to yield must be running", 59 thread: &Thread{ 60 status: ThreadDead, 61 }, 62 wantPanic: "Thread to yield is not running", 63 }, 64 { 65 name: "Caller of thread to yield must be OK", 66 thread: &Thread{ 67 status: ThreadOK, 68 caller: &Thread{ 69 status: ThreadDead, 70 }, 71 }, 72 wantPanic: "Caller of thread to yield is not OK", 73 }, 74 } 75 for _, tt := range tests { 76 t.Run(tt.name, func(t *testing.T) { 77 th := tt.thread 78 gotPanic := func() (res interface{}) { 79 defer func() { res = recover() }() 80 _, _ = th.Yield(tt.args.args) 81 return 82 }() 83 if !reflect.DeepEqual(gotPanic, tt.wantPanic) { 84 t.Errorf("Thread.Yield() panic got %v, want %v", gotPanic, tt.wantPanic) 85 } 86 }) 87 } 88 } 89 90 func TestThread_end(t *testing.T) { 91 type args struct { 92 args []Value 93 err error 94 extra interface{} 95 } 96 quotaErr := ContextTerminationError{message: "boo!"} 97 tests := []struct { 98 name string 99 thread *Thread 100 args args 101 wantPanic interface{} 102 }{ 103 { 104 name: "Thread to end must be running", 105 thread: &Thread{ 106 status: ThreadDead, 107 caller: &Thread{}, 108 resumeCh: make(chan valuesError), 109 }, 110 wantPanic: "Called Thread.end on a non-running thread", 111 }, 112 { 113 name: "Caller of thread to end must be OK", 114 thread: &Thread{ 115 status: ThreadOK, 116 caller: &Thread{ 117 status: ThreadDead, 118 }, 119 resumeCh: make(chan valuesError), 120 }, 121 wantPanic: "Caller thread of ending thread is not OK", 122 }, 123 { 124 name: "Thread must not run out of resources", 125 thread: &Thread{ 126 status: ThreadOK, 127 caller: &Thread{ 128 resumeCh: make(chan valuesError, 1), 129 }, 130 resumeCh: make(chan valuesError), 131 }, 132 args: args{ 133 extra: quotaErr, 134 }, 135 wantPanic: quotaErr, 136 }, 137 } 138 for _, tt := range tests { 139 t.Run(tt.name, func(t *testing.T) { 140 th := tt.thread 141 th.Runtime = &Runtime{} // So releasing resources works. 142 gotPanic := func() (res interface{}) { 143 defer func() { res = recover() }() 144 caller := th.caller // The caller is removed when th is killed 145 th.end(tt.args.args, tt.args.err, tt.args.extra) 146 _, _ = caller.getResumeValues() 147 return 148 }() 149 if gotPanic != tt.wantPanic { 150 t.Errorf("Thread.end() panic got %#v, want %#v", gotPanic, tt.wantPanic) 151 } 152 }) 153 } 154 }