go.mway.dev/x@v0.0.0-20240520034138-950aede9a3fb/env/var_test.go (about)

     1  // Copyright (c) 2023 Matt Way
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to
     5  // deal in the Software without restriction, including without limitation the
     6  // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
     7  // sell copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    18  // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    19  // IN THE THE SOFTWARE.
    20  
    21  package env
    22  
    23  import (
    24  	"errors"
    25  	"os"
    26  	"testing"
    27  	"unsafe"
    28  
    29  	"github.com/google/uuid"
    30  	"github.com/stretchr/testify/require"
    31  )
    32  
    33  func TestVar_NotExists(t *testing.T) {
    34  	key := uuid.New().String()
    35  
    36  	v := NewVar(key)
    37  	require.Equal(t, key, v.Key())
    38  	require.Empty(t, v.Value())
    39  	require.False(t, v.exists)
    40  
    41  	envValue, exists := os.LookupEnv(v.Key())
    42  	require.False(t, exists)
    43  	require.Empty(t, envValue)
    44  
    45  	require.NoError(t, v.Set(t.Name()))
    46  	envValue, exists = os.LookupEnv(v.Key())
    47  	require.True(t, exists)
    48  	require.Equal(t, t.Name(), envValue)
    49  	require.Equal(t, t.Name(), v.Value())
    50  
    51  	require.NoError(t, v.Restore())
    52  	envValue, exists = os.LookupEnv(v.Key())
    53  	require.False(t, exists)
    54  	require.Empty(t, envValue)
    55  	require.Empty(t, v.Value())
    56  }
    57  
    58  func TestVar_Exists(t *testing.T) {
    59  	key := uuid.New().String()
    60  
    61  	// Ensure there is a value to start.
    62  	require.NoError(t, os.Setenv(key, t.Name()))
    63  	defer func() {
    64  		require.NoError(t, os.Unsetenv(key))
    65  	}()
    66  
    67  	v := NewVar(key)
    68  	require.Equal(t, key, v.Key())
    69  	require.Equal(t, t.Name(), v.Value())
    70  	require.True(t, v.exists)
    71  
    72  	envValue, exists := os.LookupEnv(v.Key())
    73  	require.True(t, exists)
    74  	require.Equal(t, t.Name(), envValue)
    75  
    76  	require.NoError(t, v.Set("override"))
    77  	envValue, exists = os.LookupEnv(v.Key())
    78  	require.True(t, exists)
    79  	require.Equal(t, "override", envValue)
    80  	require.Equal(t, "override", v.Value())
    81  
    82  	require.NoError(t, v.Restore())
    83  	envValue, exists = os.LookupEnv(v.Key())
    84  	require.True(t, exists)
    85  	require.Equal(t, t.Name(), envValue)
    86  	require.Equal(t, t.Name(), v.Value())
    87  }
    88  
    89  func TestVar_Load(t *testing.T) {
    90  	key := uuid.New().String()
    91  
    92  	// Load a previously unset env.
    93  	v := NewVar(key)
    94  	defer v.MustUnset()
    95  
    96  	require.NoError(t, os.Setenv(key, t.Name()))
    97  	v.Load()
    98  	require.Equal(t, t.Name(), v.Value())
    99  
   100  	// Load a previously set env.
   101  	v = NewVar(key)
   102  	require.Equal(t, t.Name(), v.Value())
   103  	require.NoError(t, os.Setenv(key, "override"))
   104  	v.Load()
   105  	require.Equal(t, "override", v.Value())
   106  }
   107  
   108  func TestVar_Clone(t *testing.T) {
   109  	var (
   110  		v1 = NewVar("foo")
   111  		v2 = v1.Clone()
   112  	)
   113  
   114  	require.Equal(t, unsafe.Pointer(v1), unsafe.Pointer(v1))
   115  	require.NotEqual(t, unsafe.Pointer(v1), unsafe.Pointer(v2))
   116  }
   117  
   118  func TestVar_Set_Error(t *testing.T) {
   119  	err := errors.New("setenv error")
   120  	withStub(&_osSetenv, osSetenvReturning(err), func() {
   121  		v := NewVar("test")
   122  		require.ErrorIs(t, v.Set("this will error"), err)
   123  		require.Panics(t, func() {
   124  			v.MustSet("this will panic")
   125  		})
   126  	})
   127  }
   128  
   129  func TestVar_Restore_Error(t *testing.T) {
   130  	err := errors.New("setenv/unsetenv error")
   131  
   132  	// Does not exist; uses os.Unsetenv
   133  	withStub(&_osUnsetenv, osUnsetenvReturning(err), func() {
   134  		v := NewVar("test")
   135  		require.ErrorIs(t, v.Restore(), err)
   136  		require.Panics(t, v.MustRestore)
   137  	})
   138  
   139  	// Exists; uses os.Setenv
   140  	withStub(&_osSetenv, osSetenvReturning(err), func() {
   141  		require.NoError(t, os.Setenv("test", "test"))
   142  		v := NewVar("test")
   143  		require.ErrorIs(t, v.Restore(), err)
   144  		require.Panics(t, v.MustRestore)
   145  	})
   146  }
   147  
   148  func TestVar_Unset_Error(t *testing.T) {
   149  	err := errors.New("setenv error")
   150  	withStub(&_osUnsetenv, osUnsetenvReturning(err), func() {
   151  		v := NewVar("test")
   152  		require.ErrorIs(t, v.Unset(), err)
   153  		require.Panics(t, v.MustUnset)
   154  	})
   155  }