go.mway.dev/x@v0.0.0-20240520034138-950aede9a3fb/sync/atomic/value_test.go (about)

     1  package atomic_test
     2  
     3  import (
     4  	"bytes"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/require"
     8  	"go.mway.dev/x/ptr"
     9  	"go.mway.dev/x/sync/atomic"
    10  )
    11  
    12  func TestValue_Load(t *testing.T) {
    13  	cases := map[string]struct {
    14  		give     any
    15  		validate func(any) bool
    16  	}{
    17  		"string": {
    18  			give: "hello world",
    19  			validate: func(x any) bool {
    20  				_, ok := x.(string)
    21  				return ok
    22  			},
    23  		},
    24  		"bytes.Buffer": {
    25  			give: bytes.NewBuffer(nil),
    26  			validate: func(x any) bool {
    27  				_, ok := x.(*bytes.Buffer)
    28  				return ok
    29  			},
    30  		},
    31  		"struct pointer": {
    32  			give: ptr.Of(testStruct{t.Name()}),
    33  			validate: func(x any) bool {
    34  				_, ok := x.(*testStruct)
    35  				return ok
    36  			},
    37  		},
    38  	}
    39  
    40  	for name, tt := range cases {
    41  		t.Run(name, func(t *testing.T) {
    42  			var (
    43  				value  = atomic.NewValue(tt.give)
    44  				actual = value.Load()
    45  			)
    46  
    47  			require.Equal(t, tt.give, actual)
    48  			require.True(t, tt.validate(actual))
    49  		})
    50  	}
    51  }
    52  
    53  func TestValue_CompareAndSwap(t *testing.T) {
    54  	var (
    55  		structA = &testStruct{"hello"}
    56  		structB = &testStruct{123}
    57  		structC = &testStruct{}
    58  		structD = &testStruct{}
    59  		value   = atomic.NewValue(structA)
    60  	)
    61  
    62  	require.False(t, value.CompareAndSwap(structB, structA))
    63  	require.False(t, value.CompareAndSwap(structB, structB))
    64  	require.True(t, value.CompareAndSwap(structA, structA))
    65  	require.True(t, value.CompareAndSwap(structA, structB))
    66  	require.True(t, value.CompareAndSwap(structB, structC))
    67  	require.False(t, value.CompareAndSwap(structD, structC))
    68  	require.True(t, value.CompareAndSwap(structC, structD))
    69  }
    70  
    71  func TestValue_Store(t *testing.T) {
    72  	value := atomic.NewValue(0)
    73  
    74  	for i := 0; i < 100; i++ {
    75  		value.Store(i)
    76  		require.Equal(t, i, value.Load())
    77  	}
    78  }
    79  
    80  func TestValue_Swap(t *testing.T) {
    81  	value := atomic.NewValue(0)
    82  
    83  	for i := 1; i < 100; i++ {
    84  		require.Equal(t, i-1, value.Swap(i))
    85  	}
    86  }
    87  
    88  type testStruct struct {
    89  	val any
    90  }