2017-10-06 15:29:20 +00:00
package mg_test
import (
"errors"
"fmt"
"testing"
"time"
"github.com/magefile/mage/mg"
)
func TestDepsRunOnce ( t * testing . T ) {
done := make ( chan struct { } )
f := func ( ) {
done <- struct { } { }
}
go mg . Deps ( f , f )
select {
case <- done :
// cool
case <- time . After ( time . Millisecond * 100 ) :
t . Fatal ( "func not run in a reasonable amount of time." )
}
select {
case <- done :
t . Fatal ( "func run twice!" )
case <- time . After ( time . Millisecond * 100 ) :
// cool... this should be plenty of time for the goroutine to have run
}
}
func TestDepsOfDeps ( t * testing . T ) {
ch := make ( chan string , 3 )
// this->f->g->h
h := func ( ) {
ch <- "h"
}
g := func ( ) {
mg . Deps ( h )
ch <- "g"
}
f := func ( ) {
mg . Deps ( g )
ch <- "f"
}
mg . Deps ( f )
res := <- ch + <- ch + <- ch
if res != "hgf" {
t . Fatal ( "expected h then g then f to run, but got " + res )
}
}
func TestDepError ( t * testing . T ) {
// TODO: this test is ugly and relies on implementation details. It should
// be recreated as a full-stack test.
f := func ( ) error {
return errors . New ( "ouch!" )
}
defer func ( ) {
err := recover ( )
if err == nil {
t . Fatal ( "expected panic, but didn't get one" )
}
actual := fmt . Sprint ( err )
if "ouch!" != actual {
t . Fatalf ( ` expected to get "ouch!" but got "%s" ` , actual )
}
} ( )
mg . Deps ( f )
}
func TestDepFatal ( t * testing . T ) {
f := func ( ) error {
return mg . Fatal ( 99 , "ouch!" )
}
defer func ( ) {
v := recover ( )
if v == nil {
t . Fatal ( "expected panic, but didn't get one" )
}
actual := fmt . Sprint ( v )
if "ouch!" != actual {
t . Fatalf ( ` expected to get "ouch!" but got "%s" ` , actual )
}
err , ok := v . ( error )
if ! ok {
t . Fatalf ( "expected recovered val to be error but was %T" , v )
}
code := mg . ExitStatus ( err )
if code != 99 {
t . Fatalf ( "Expected exit status 99, but got %v" , code )
}
} ( )
mg . Deps ( f )
}
func TestDepTwoFatal ( t * testing . T ) {
f := func ( ) error {
return mg . Fatal ( 99 , "ouch!" )
}
g := func ( ) error {
return mg . Fatal ( 11 , "bang!" )
}
defer func ( ) {
v := recover ( )
if v == nil {
t . Fatal ( "expected panic, but didn't get one" )
}
actual := fmt . Sprint ( v )
// order is non-deterministic, so check for both orders
if "ouch!\nbang!" != actual && "bang!\nouch!" != actual {
t . Fatalf ( ` expected to get "ouch!" and "bang!" but got "%s" ` , actual )
}
err , ok := v . ( error )
if ! ok {
t . Fatalf ( "expected recovered val to be error but was %T" , v )
}
code := mg . ExitStatus ( err )
// two different error codes returns, so we give up and just use error
// code 1.
if code != 1 {
t . Fatalf ( "Expected exit status 1, but got %v" , code )
}
} ( )
mg . Deps ( f , g )
}
2018-01-03 19:19:49 +00:00
func TestDepWithUnhandledFunc ( t * testing . T ) {
defer func ( ) {
err := recover ( )
expected := "Invalid type for dependent function: func(string) string. Dependencies must be func(), func() error, func(context.Context) or func(context.Context) error"
actual , ok := err . ( error )
if ! ok {
t . Fatalf ( "Expected type string from panic" )
}
if actual . Error ( ) != expected {
t . Fatalf ( "Expected panic %v but got %v" , expected , err )
}
} ( )
var NotValid func ( string ) string = func ( a string ) string {
return a
}
mg . Deps ( NotValid )
}