|  | package failer | 
|  |  | 
|  | import ( | 
|  | "fmt" | 
|  | "sync" | 
|  |  | 
|  | "github.com/onsi/ginkgo/types" | 
|  | ) | 
|  |  | 
|  | type Failer struct { | 
|  | lock    *sync.Mutex | 
|  | failure types.SpecFailure | 
|  | state   types.SpecState | 
|  | } | 
|  |  | 
|  | func New() *Failer { | 
|  | return &Failer{ | 
|  | lock:  &sync.Mutex{}, | 
|  | state: types.SpecStatePassed, | 
|  | } | 
|  | } | 
|  |  | 
|  | func (f *Failer) Panic(location types.CodeLocation, forwardedPanic interface{}) { | 
|  | f.lock.Lock() | 
|  | defer f.lock.Unlock() | 
|  |  | 
|  | if f.state == types.SpecStatePassed { | 
|  | f.state = types.SpecStatePanicked | 
|  | f.failure = types.SpecFailure{ | 
|  | Message:        "Test Panicked", | 
|  | Location:       location, | 
|  | ForwardedPanic: fmt.Sprintf("%v", forwardedPanic), | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | func (f *Failer) Timeout(location types.CodeLocation) { | 
|  | f.lock.Lock() | 
|  | defer f.lock.Unlock() | 
|  |  | 
|  | if f.state == types.SpecStatePassed { | 
|  | f.state = types.SpecStateTimedOut | 
|  | f.failure = types.SpecFailure{ | 
|  | Message:  "Timed out", | 
|  | Location: location, | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | func (f *Failer) Fail(message string, location types.CodeLocation) { | 
|  | f.lock.Lock() | 
|  | defer f.lock.Unlock() | 
|  |  | 
|  | if f.state == types.SpecStatePassed { | 
|  | f.state = types.SpecStateFailed | 
|  | f.failure = types.SpecFailure{ | 
|  | Message:  message, | 
|  | Location: location, | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | func (f *Failer) Drain(componentType types.SpecComponentType, componentIndex int, componentCodeLocation types.CodeLocation) (types.SpecFailure, types.SpecState) { | 
|  | f.lock.Lock() | 
|  | defer f.lock.Unlock() | 
|  |  | 
|  | failure := f.failure | 
|  | outcome := f.state | 
|  | if outcome != types.SpecStatePassed { | 
|  | failure.ComponentType = componentType | 
|  | failure.ComponentIndex = componentIndex | 
|  | failure.ComponentCodeLocation = componentCodeLocation | 
|  | } | 
|  |  | 
|  | f.state = types.SpecStatePassed | 
|  | f.failure = types.SpecFailure{} | 
|  |  | 
|  | return failure, outcome | 
|  | } | 
|  |  | 
|  | func (f *Failer) Skip(message string, location types.CodeLocation) { | 
|  | f.lock.Lock() | 
|  | defer f.lock.Unlock() | 
|  |  | 
|  | if f.state == types.SpecStatePassed { | 
|  | f.state = types.SpecStateSkipped | 
|  | f.failure = types.SpecFailure{ | 
|  | Message:  message, | 
|  | Location: location, | 
|  | } | 
|  | } | 
|  | } |