go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/sdk/promise/promise_test.go (about)

     1  package promise
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"go.charczuk.com/sdk/assert"
     9  )
    10  
    11  func Test_Promise(t *testing.T) {
    12  	p := New(context.Background(), func(ictx context.Context) (string, error) {
    13  		return "ok!", nil
    14  	})
    15  
    16  	res := make(chan PromiseResult[string], 1)
    17  	go func() {
    18  		got := <-p.Await()
    19  		res <- got
    20  	}()
    21  
    22  	final, ok := <-res
    23  	assert.ItsEqual(t, true, ok)
    24  	assert.ItsNil(t, final.Err)
    25  	assert.ItsEqual(t, "ok!", final.Value)
    26  }
    27  
    28  func Test_Promise_Wait(t *testing.T) {
    29  	p := New(context.Background(), func(ictx context.Context) (string, error) {
    30  		return "ok!", nil
    31  	})
    32  
    33  	final := p.Wait()
    34  	assert.ItsNil(t, final.Err)
    35  	assert.ItsEqual(t, "ok!", final.Value)
    36  }
    37  
    38  func Test_Promise_Wait_err(t *testing.T) {
    39  	p := New(context.Background(), func(ictx context.Context) (string, error) {
    40  		return "ok!", fmt.Errorf("not-ok!")
    41  	})
    42  
    43  	final := p.Wait()
    44  	assert.ItsNotNil(t, final.Err)
    45  	assert.ItsEqual(t, "ok!", final.Value)
    46  	assert.ItsEqual(t, "not-ok!", final.Err.Error())
    47  }
    48  
    49  func Test_Promise_Wait_closed(t *testing.T) {
    50  	p := New(context.Background(), func(ictx context.Context) (string, error) {
    51  		return "ok!", fmt.Errorf("not-ok!")
    52  	})
    53  
    54  	final := p.Wait()
    55  	assert.ItsNotNil(t, final.Err)
    56  	assert.ItsEqual(t, "ok!", final.Value)
    57  	assert.ItsEqual(t, "not-ok!", final.Err.Error())
    58  
    59  	final = p.Wait()
    60  	assert.ItsNotNil(t, final.Err)
    61  	assert.ItsEqual(t, "", final.Value)
    62  	assert.ItsEqual(t, ErrAlreadyResolved, final.Err)
    63  }
    64  
    65  func Test_Promise_cancel(t *testing.T) {
    66  	p := New(context.Background(), func(ictx context.Context) (string, error) {
    67  		<-ictx.Done()
    68  		return "", fmt.Errorf("did cancel!")
    69  	})
    70  
    71  	res := make(chan PromiseResult[string], 1)
    72  	go func() {
    73  		got := <-p.Await()
    74  		res <- got
    75  	}()
    76  
    77  	// this will trigger <-ictx.Done()
    78  	p.Cancel()
    79  
    80  	final, ok := <-res
    81  	assert.ItsEqual(t, true, ok)
    82  	assert.ItsNotNil(t, final.Err)
    83  	assert.ItsEqual(t, "did cancel!", final.Err.Error())
    84  }
    85  
    86  func Test_Promise_cancel_external(t *testing.T) {
    87  	ctx, cancel := context.WithCancel(context.Background())
    88  	p := New(ctx, func(ictx context.Context) (string, error) {
    89  		<-ictx.Done()
    90  		return "", fmt.Errorf("did cancel!")
    91  	})
    92  
    93  	res := make(chan PromiseResult[string], 1)
    94  	go func() {
    95  		got := <-p.Await()
    96  		res <- got
    97  	}()
    98  
    99  	// this will trigger <-ictx.Done()
   100  	cancel()
   101  
   102  	final, ok := <-res
   103  	assert.ItsEqual(t, true, ok)
   104  	assert.ItsNotNil(t, final.Err)
   105  	assert.ItsEqual(t, "did cancel!", final.Err.Error())
   106  }
   107  
   108  func Test_Promise_cancel_noAwait(t *testing.T) {
   109  	p := New(context.Background(), func(ictx context.Context) (string, error) {
   110  		<-ictx.Done()
   111  		return "", fmt.Errorf("did cancel!")
   112  	})
   113  
   114  	// this will trigger <-ictx.Done()
   115  	p.Cancel()
   116  }