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  }