github.com/anthropics/anthropic-sdk-go@v1.70.1/internal/apijson/enum_test.go (about) 1 package apijson 2 3 import ( 4 "reflect" 5 "testing" 6 ) 7 8 type EnumStruct struct { 9 NormalString string `json:"normal_string"` 10 StringEnum string `json:"string_enum"` 11 NamedEnum NamedEnumType `json:"named_enum"` 12 13 IntEnum int `json:"int_enum"` 14 BoolEnum bool `json:"bool_enum"` 15 16 WeirdBoolEnum bool `json:"weird_bool_enum"` 17 } 18 19 func (o *EnumStruct) UnmarshalJSON(data []byte) error { 20 return UnmarshalRoot(data, o) 21 } 22 23 func init() { 24 RegisterFieldValidator[EnumStruct]("string_enum", "one", "two", "three") 25 RegisterFieldValidator[EnumStruct]("int_enum", 200, 404) 26 RegisterFieldValidator[EnumStruct]("bool_enum", false) 27 RegisterFieldValidator[EnumStruct]("weird_bool_enum", true, false) 28 } 29 30 type NamedEnumType string 31 32 const ( 33 NamedEnumOne NamedEnumType = "one" 34 NamedEnumTwo NamedEnumType = "two" 35 NamedEnumThree NamedEnumType = "three" 36 ) 37 38 func (e NamedEnumType) IsKnown() bool { 39 return e == NamedEnumOne || e == NamedEnumTwo || e == NamedEnumThree 40 } 41 42 func TestEnumStructStringValidator(t *testing.T) { 43 var ( 44 exact = exactness{} 45 loose = exactness{coercions: 1} 46 extras = exactness{extras: hasExtras} 47 ) 48 cases := map[string]struct { 49 exactness 50 EnumStruct 51 }{ 52 `{"string_enum":"one"}`: {exact, EnumStruct{StringEnum: "one"}}, 53 `{"string_enum":"two"}`: {exact, EnumStruct{StringEnum: "two"}}, 54 `{"string_enum":"three"}`: {exact, EnumStruct{StringEnum: "three"}}, 55 `{"string_enum":"none"}`: {loose, EnumStruct{StringEnum: "none"}}, 56 `{"int_enum":200}`: {exact, EnumStruct{IntEnum: 200}}, 57 `{"int_enum":404}`: {exact, EnumStruct{IntEnum: 404}}, 58 `{"int_enum":500}`: {loose, EnumStruct{IntEnum: 500}}, 59 `{"bool_enum":false}`: {exact, EnumStruct{BoolEnum: false}}, 60 `{"bool_enum":true}`: {loose, EnumStruct{BoolEnum: true}}, 61 `{"weird_bool_enum":true}`: {exact, EnumStruct{WeirdBoolEnum: true}}, 62 `{"weird_bool_enum":false}`: {exact, EnumStruct{WeirdBoolEnum: false}}, 63 64 `{"named_enum":"one"}`: {exact, EnumStruct{NamedEnum: NamedEnumOne}}, 65 `{"named_enum":"none"}`: {loose, EnumStruct{NamedEnum: "none"}}, 66 67 `{"string_enum":"one","named_enum":"one"}`: {exact, EnumStruct{NamedEnum: "one", StringEnum: "one"}}, 68 `{"string_enum":"four","named_enum":"one"}`: { 69 loose, 70 EnumStruct{NamedEnum: "one", StringEnum: "four"}, 71 }, 72 `{"string_enum":"one","named_enum":"four"}`: { 73 loose, EnumStruct{NamedEnum: "four", StringEnum: "one"}, 74 }, 75 `{"wrong_key":"one"}`: {extras, EnumStruct{StringEnum: ""}}, 76 } 77 78 for raw, expected := range cases { 79 var dst EnumStruct 80 81 dec := decoderBuilder{root: true} 82 exactness, _ := dec.unmarshalWithExactness([]byte(raw), &dst) 83 84 if !reflect.DeepEqual(dst, expected.EnumStruct) { 85 t.Fatalf("failed equality check %#v", dst) 86 } 87 88 if exactness != expected.exactness { 89 t.Fatalf("exactness got %+v expected %+v %s", exactness, expected.exactness, raw) 90 } 91 } 92 }