github.com/rclone/rclone@v1.66.1-0.20240517100346-7b89735ae726/fs/enum_test.go (about) 1 package fs 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 "github.com/stretchr/testify/require" 10 ) 11 12 type choices struct{} 13 14 func (choices) Choices() []string { 15 return []string{ 16 choiceA: "A", 17 choiceB: "B", 18 choiceC: "C", 19 } 20 } 21 22 type choice = Enum[choices] 23 24 const ( 25 choiceA choice = iota 26 choiceB 27 choiceC 28 ) 29 30 // Check it satisfies the interfaces 31 var ( 32 _ flagger = (*choice)(nil) 33 _ flaggerNP = choice(0) 34 ) 35 36 func TestEnumString(t *testing.T) { 37 for _, test := range []struct { 38 in choice 39 want string 40 }{ 41 {choiceA, "A"}, 42 {choiceB, "B"}, 43 {choiceC, "C"}, 44 {choice(100), "Unknown(100)"}, 45 } { 46 got := test.in.String() 47 assert.Equal(t, test.want, got) 48 } 49 } 50 51 func TestEnumType(t *testing.T) { 52 assert.Equal(t, "A|B|C", choiceA.Type()) 53 } 54 55 // Enum with Type() on the choices 56 type choicestype struct{} 57 58 func (choicestype) Choices() []string { 59 return []string{} 60 } 61 62 func (choicestype) Type() string { 63 return "potato" 64 } 65 66 type choicetype = Enum[choicestype] 67 68 func TestEnumTypeWithFunction(t *testing.T) { 69 assert.Equal(t, "potato", choicetype(0).Type()) 70 } 71 72 func TestEnumHelp(t *testing.T) { 73 assert.Equal(t, "A, B, C", choice(0).Help()) 74 } 75 76 func TestEnumSet(t *testing.T) { 77 for _, test := range []struct { 78 in string 79 want choice 80 err bool 81 }{ 82 {"A", choiceA, false}, 83 {"B", choiceB, false}, 84 {"C", choiceC, false}, 85 {"D", choice(100), true}, 86 } { 87 var got choice 88 err := got.Set(test.in) 89 if test.err { 90 require.Error(t, err) 91 } else { 92 require.NoError(t, err) 93 assert.Equal(t, test.want, got) 94 } 95 } 96 } 97 98 func TestEnumScan(t *testing.T) { 99 var v choice 100 n, err := fmt.Sscan(" A ", &v) 101 require.NoError(t, err) 102 assert.Equal(t, 1, n) 103 assert.Equal(t, choiceA, v) 104 } 105 106 func TestEnumUnmarshalJSON(t *testing.T) { 107 for _, test := range []struct { 108 in string 109 want choice 110 err string 111 }{ 112 {`"A"`, choiceA, ""}, 113 {`"B"`, choiceB, ""}, 114 {`0`, choiceA, ""}, 115 {`1`, choiceB, ""}, 116 {`"D"`, choice(0), `invalid choice "D" from: A, B, C`}, 117 {`100`, choice(0), `100 is out of range: must be 0..3`}, 118 } { 119 var got choice 120 err := json.Unmarshal([]byte(test.in), &got) 121 if test.err != "" { 122 require.Error(t, err, test.in) 123 assert.ErrorContains(t, err, test.err) 124 } else { 125 require.NoError(t, err, test.in) 126 } 127 assert.Equal(t, test.want, got, test.in) 128 } 129 } 130 131 func TestEnumMarshalJSON(t *testing.T) { 132 for _, test := range []struct { 133 in choice 134 want string 135 }{ 136 {choiceA, `"A"`}, 137 {choiceB, `"B"`}, 138 } { 139 got, err := json.Marshal(&test.in) 140 require.NoError(t, err) 141 assert.Equal(t, test.want, string(got), fmt.Sprintf("%#v", test.in)) 142 } 143 }