github.com/rochacon/deis@v1.0.2-0.20150903015341-6839b592a1ff/Godeps/_workspace/src/gopkg.in/tomb.v1/tomb_test.go (about)

     1  package tomb_test
     2  
     3  import (
     4  	"errors"
     5  	"gopkg.in/tomb.v1"
     6  	"reflect"
     7  	"testing"
     8  )
     9  
    10  func TestNewTomb(t *testing.T) {
    11  	tb := &tomb.Tomb{}
    12  	testState(t, tb, false, false, tomb.ErrStillAlive)
    13  
    14  	tb.Done()
    15  	testState(t, tb, true, true, nil)
    16  }
    17  
    18  func TestKill(t *testing.T) {
    19  	// a nil reason flags the goroutine as dying
    20  	tb := &tomb.Tomb{}
    21  	tb.Kill(nil)
    22  	testState(t, tb, true, false, nil)
    23  
    24  	// a non-nil reason now will override Kill
    25  	err := errors.New("some error")
    26  	tb.Kill(err)
    27  	testState(t, tb, true, false, err)
    28  
    29  	// another non-nil reason won't replace the first one
    30  	tb.Kill(errors.New("ignore me"))
    31  	testState(t, tb, true, false, err)
    32  
    33  	tb.Done()
    34  	testState(t, tb, true, true, err)
    35  }
    36  
    37  func TestKillf(t *testing.T) {
    38  	tb := &tomb.Tomb{}
    39  
    40  	err := tb.Killf("BO%s", "OM")
    41  	if s := err.Error(); s != "BOOM" {
    42  		t.Fatalf(`Killf("BO%s", "OM"): want "BOOM", got %q`, s)
    43  	}
    44  	testState(t, tb, true, false, err)
    45  
    46  	// another non-nil reason won't replace the first one
    47  	tb.Killf("ignore me")
    48  	testState(t, tb, true, false, err)
    49  
    50  	tb.Done()
    51  	testState(t, tb, true, true, err)
    52  }
    53  
    54  func TestErrDying(t *testing.T) {
    55  	// ErrDying being used properly, after a clean death.
    56  	tb := &tomb.Tomb{}
    57  	tb.Kill(nil)
    58  	tb.Kill(tomb.ErrDying)
    59  	testState(t, tb, true, false, nil)
    60  
    61  	// ErrDying being used properly, after an errorful death.
    62  	err := errors.New("some error")
    63  	tb.Kill(err)
    64  	tb.Kill(tomb.ErrDying)
    65  	testState(t, tb, true, false, err)
    66  
    67  	// ErrDying being used badly, with an alive tomb.
    68  	tb = &tomb.Tomb{}
    69  	defer func() {
    70  		err := recover()
    71  		if err != "tomb: Kill with ErrDying while still alive" {
    72  			t.Fatalf("Wrong panic on Kill(ErrDying): %v", err)
    73  		}
    74  		testState(t, tb, false, false, tomb.ErrStillAlive)
    75  	}()
    76  	tb.Kill(tomb.ErrDying)
    77  }
    78  
    79  func testState(t *testing.T, tb *tomb.Tomb, wantDying, wantDead bool, wantErr error) {
    80  	select {
    81  	case <-tb.Dying():
    82  		if !wantDying {
    83  			t.Error("<-Dying: should block")
    84  		}
    85  	default:
    86  		if wantDying {
    87  			t.Error("<-Dying: should not block")
    88  		}
    89  	}
    90  	seemsDead := false
    91  	select {
    92  	case <-tb.Dead():
    93  		if !wantDead {
    94  			t.Error("<-Dead: should block")
    95  		}
    96  		seemsDead = true
    97  	default:
    98  		if wantDead {
    99  			t.Error("<-Dead: should not block")
   100  		}
   101  	}
   102  	if err := tb.Err(); err != wantErr {
   103  		t.Errorf("Err: want %#v, got %#v", wantErr, err)
   104  	}
   105  	if wantDead && seemsDead {
   106  		waitErr := tb.Wait()
   107  		switch {
   108  		case waitErr == tomb.ErrStillAlive:
   109  			t.Errorf("Wait should not return ErrStillAlive")
   110  		case !reflect.DeepEqual(waitErr, wantErr):
   111  			t.Errorf("Wait: want %#v, got %#v", wantErr, waitErr)
   112  		}
   113  	}
   114  }