github.com/rclone/rclone@v1.66.1-0.20240517100346-7b89735ae726/fs/bits_test.go (about)

     1  package fs
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strconv"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  type bits = Bits[bitsChoices]
    14  
    15  const (
    16  	bitA bits = 1 << iota
    17  	bitB
    18  	bitC
    19  )
    20  
    21  type bitsChoices struct{}
    22  
    23  func (bitsChoices) Choices() []BitsChoicesInfo {
    24  	return []BitsChoicesInfo{
    25  		{uint64(0), "OFF"},
    26  		{uint64(bitA), "A"},
    27  		{uint64(bitB), "B"},
    28  		{uint64(bitC), "C"},
    29  	}
    30  }
    31  
    32  // Check it satisfies the interfaces
    33  var (
    34  	_ flagger   = (*bits)(nil)
    35  	_ flaggerNP = bits(0)
    36  )
    37  
    38  func TestBitsString(t *testing.T) {
    39  	assert.Equal(t, "OFF", bits(0).String())
    40  	assert.Equal(t, "A", (bitA).String())
    41  	assert.Equal(t, "A,B", (bitA | bitB).String())
    42  	assert.Equal(t, "A,B,C", (bitA | bitB | bitC).String())
    43  	assert.Equal(t, "A,Unknown-0x8000", (bitA | bits(0x8000)).String())
    44  }
    45  
    46  func TestBitsHelp(t *testing.T) {
    47  	assert.Equal(t, "OFF, A, B, C", bits(0).Help())
    48  }
    49  
    50  func TestBitsSet(t *testing.T) {
    51  	for _, test := range []struct {
    52  		in      string
    53  		want    bits
    54  		wantErr string
    55  	}{
    56  		{"", bits(0), ""},
    57  		{"B", bitB, ""},
    58  		{"B,A", bitB | bitA, ""},
    59  		{"a,b,C", bitA | bitB | bitC, ""},
    60  		{"A,B,unknown,E", 0, `invalid choice "unknown" from: OFF, A, B, C`},
    61  	} {
    62  		f := bits(0xffffffffffffffff)
    63  		initial := f
    64  		err := f.Set(test.in)
    65  		if err != nil {
    66  			if test.wantErr == "" {
    67  				t.Errorf("Got an error when not expecting one on %q: %v", test.in, err)
    68  			} else {
    69  				assert.Contains(t, err.Error(), test.wantErr)
    70  			}
    71  			assert.Equal(t, initial, f, test.want)
    72  		} else {
    73  			if test.wantErr != "" {
    74  				t.Errorf("Got no error when expecting one on %q", test.in)
    75  			} else {
    76  				assert.Equal(t, test.want, f)
    77  			}
    78  		}
    79  
    80  	}
    81  }
    82  
    83  func TestBitsIsSet(t *testing.T) {
    84  	b := bitA | bitB
    85  	assert.True(t, b.IsSet(bitA))
    86  	assert.True(t, b.IsSet(bitB))
    87  	assert.True(t, b.IsSet(bitA|bitB))
    88  	assert.False(t, b.IsSet(bitC))
    89  	assert.False(t, b.IsSet(bitA|bitC))
    90  }
    91  
    92  func TestBitsType(t *testing.T) {
    93  	f := bits(0)
    94  	assert.Equal(t, "Bits", f.Type())
    95  }
    96  
    97  func TestBitsScan(t *testing.T) {
    98  	var v bits
    99  	n, err := fmt.Sscan(" C,B ", &v)
   100  	require.NoError(t, err)
   101  	assert.Equal(t, 1, n)
   102  	assert.Equal(t, bitC|bitB, v)
   103  }
   104  
   105  func TestBitsUnmarshallJSON(t *testing.T) {
   106  	for _, test := range []struct {
   107  		in      string
   108  		want    bits
   109  		wantErr string
   110  	}{
   111  		{`""`, bits(0), ""},
   112  		{`"B"`, bitB, ""},
   113  		{`"B,A"`, bitB | bitA, ""},
   114  		{`"A,B,C"`, bitA | bitB | bitC, ""},
   115  		{`"A,B,unknown,E"`, 0, `invalid choice "unknown" from: OFF, A, B, C`},
   116  		{`0`, bits(0), ""},
   117  		{strconv.Itoa(int(bitB)), bitB, ""},
   118  		{strconv.Itoa(int(bitB | bitA)), bitB | bitA, ""},
   119  	} {
   120  		f := bits(0xffffffffffffffff)
   121  		initial := f
   122  		err := json.Unmarshal([]byte(test.in), &f)
   123  		if err != nil {
   124  			if test.wantErr == "" {
   125  				t.Errorf("Got an error when not expecting one on %q: %v", test.in, err)
   126  			} else {
   127  				assert.Contains(t, err.Error(), test.wantErr)
   128  			}
   129  			assert.Equal(t, initial, f, test.want)
   130  		} else {
   131  			if test.wantErr != "" {
   132  				t.Errorf("Got no error when expecting one on %q", test.in)
   133  			} else {
   134  				assert.Equal(t, test.want, f)
   135  			}
   136  		}
   137  	}
   138  }
   139  func TestBitsMarshalJSON(t *testing.T) {
   140  	for _, test := range []struct {
   141  		in   bits
   142  		want string
   143  	}{
   144  		{bitA | bitC, `"A,C"`},
   145  		{0, `"OFF"`},
   146  	} {
   147  		got, err := json.Marshal(&test.in)
   148  		require.NoError(t, err)
   149  		assert.Equal(t, test.want, string(got), fmt.Sprintf("%#v", test.in))
   150  	}
   151  }