forked from onsi/ginkgo
/
runnable_node.go
120 lines (100 loc) · 2.52 KB
/
runnable_node.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package ginkgo
import (
"fmt"
"github.com/onsi/ginkgo/types"
"reflect"
"time"
)
type runnableNode struct {
isAsync bool
asyncFunc func(Done)
syncFunc func()
codeLocation types.CodeLocation
timeoutThreshold time.Duration
}
func newRunnableNode(body interface{}, codeLocation types.CodeLocation, timeout time.Duration) *runnableNode {
bodyType := reflect.TypeOf(body)
if bodyType.Kind() != reflect.Func {
panic(fmt.Sprintf("Expected a function but got something else at %v", codeLocation))
}
switch bodyType.NumIn() {
case 0:
return &runnableNode{
isAsync: false,
asyncFunc: nil,
syncFunc: body.(func()),
codeLocation: codeLocation,
timeoutThreshold: timeout,
}
case 1:
if bodyType.In(0) != reflect.TypeOf((*Done)(nil)).Elem() {
panic(fmt.Sprintf("Must pass a Done channel to function at %v", codeLocation))
}
return &runnableNode{
isAsync: true,
asyncFunc: body.(func(Done)),
syncFunc: nil,
codeLocation: codeLocation,
timeoutThreshold: timeout,
}
}
panic(fmt.Sprintf("Too many arguments to function at %v", codeLocation))
}
func (runnable *runnableNode) run() (outcome runOutcome, failure failureData) {
done := make(chan interface{}, 1)
defer func() {
if e := recover(); e != nil {
outcome = runOutcomePanicked
failure = failureData{
message: "Test Panicked",
codeLocation: types.GenerateCodeLocation(2),
forwardedPanic: e,
}
}
}()
if runnable.isAsync {
go runnable.asyncFunc(done)
} else {
runnable.syncFunc()
done <- true
}
select {
case <-done:
outcome = runOutcomeCompleted
case <-time.After(runnable.timeoutThreshold):
outcome = runOutcomeTimedOut
failure = failureData{
message: "Timed out",
codeLocation: runnable.codeLocation,
}
}
return
}
//It Node
type itNode struct {
*runnableNode
flag flagType
text string
}
func newItNode(text string, body interface{}, flag flagType, codeLocation types.CodeLocation, timeout time.Duration) *itNode {
return &itNode{
runnableNode: newRunnableNode(body, codeLocation, timeout),
flag: flag,
text: text,
}
}
func (node *itNode) generateExamples() []*example {
return []*example{newExample(node)}
}
func (node *itNode) nodeType() nodeType {
return nodeTypeIt
}
func (node *itNode) getText() string {
return node.text
}
func (node *itNode) getFlag() flagType {
return node.flag
}
func (node *itNode) getCodeLocation() types.CodeLocation {
return node.codeLocation
}