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 }