enum_test.go 2.6 KB

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