Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions cmd/generate-bindings/solana/anchor-go/generator/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,10 @@ func (g *Generator) gen_complexEnum(name string, docs []string, typ idl.IdlTypeD

argBody.Switch(Id("tmp").Dot("Enum")).
BlockFunc(func(switchGroup *Group) {
interfaceType := g.idl.Types.ByName(enumName)
interfaceType := g.idl.Types.ByName(name)
if interfaceType == nil {
panic(fmt.Errorf("complex enum type %q not found in IDL types", name))
}

for variantIndex, variant := range interfaceType.Ty.(*idl.IdlTypeDefTyEnum).Variants {
variantTypeNameComplex := formatComplexEnumVariantTypeName(enumName, variant.Name)
Expand Down Expand Up @@ -226,8 +229,10 @@ func (g *Generator) gen_complexEnum(name string, docs []string, typ idl.IdlTypeD
argBody.List(Id("tmp")).Op(":=").Id(formatEnumContainerName(enumTypeName)).Block()
argBody.Switch(Id("realvalue").Op(":=").Id("value").Op(".").Parens(Type())).
BlockFunc(func(switchGroup *Group) {
// TODO: maybe it's from idl.Accounts ???
interfaceType := g.idl.Types.ByName(enumTypeName)
interfaceType := g.idl.Types.ByName(name)
if interfaceType == nil {
panic(fmt.Errorf("complex enum type %q not found in IDL types", name))
}
for variantIndex, variant := range interfaceType.Ty.(*idl.IdlTypeDefTyEnum).Variants {
variantTypeNameStruct := formatComplexEnumVariantTypeName(enumTypeName, variant.Name)

Expand Down
100 changes: 100 additions & 0 deletions cmd/generate-bindings/solana/anchor-go/generator/types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//nolint:all // Forked from anchor-go generator, maintaining original code structure
package generator

import (
"testing"

"github.com/gagliardetto/anchor-go/idl"
"github.com/gagliardetto/anchor-go/idl/idltype"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func makeComplexEnumIDL(enumName string) *idl.Idl {
enumType := &idl.IdlTypeDefTyEnum{
Kind: "enum",
Variants: idl.VariantSlice{
{Name: "Simple"},
{
Name: "WithFields",
Fields: idl.Some[idl.IdlDefinedFields](idl.IdlDefinedFieldsNamed{
{Name: "value", Ty: &idltype.U64{}},
}),
},
},
}

return &idl.Idl{
Types: idl.IdTypeDef_slice{
{
Name: enumName,
Ty: enumType,
},
},
}
}

func TestGenComplexEnum_ConsecutiveUppercase(t *testing.T) {
// "HTTPStatus" is stored in the IDL as-is. ToCamelUpper converts it to
// "HttpStatus" (via snake_case intermediary), so ByName("HttpStatus")
// won't find the original "HTTPStatus" entry and returns nil.
idlData := makeComplexEnumIDL("HTTPStatus")
gen := &Generator{
idl: idlData,
options: &GeneratorOptions{Package: "test"},
}

// Register the complex enum as the generator normally would.
for _, typ := range gen.idl.Types {
registerComplexEnums(typ)
}

outputFile, err := gen.genfile_types()
require.NoError(t, err, "genfile_types should not panic or error for enum named HTTPStatus")
require.NotNil(t, outputFile)

generatedCode := outputFile.File.GoString()
assert.Contains(t, generatedCode, "HttpStatus")
}

func TestGenComplexEnum_SnakeCaseName(t *testing.T) {
// "my_status" is stored in the IDL. ToCamelUpper converts it to
// "MyStatus", so ByName("MyStatus") won't find "my_status".
idlData := makeComplexEnumIDL("my_status")
gen := &Generator{
idl: idlData,
options: &GeneratorOptions{Package: "test"},
}

for _, typ := range gen.idl.Types {
registerComplexEnums(typ)
}

outputFile, err := gen.genfile_types()
require.NoError(t, err, "genfile_types should not panic or error for enum named my_status")
require.NotNil(t, outputFile)

generatedCode := outputFile.File.GoString()
assert.Contains(t, generatedCode, "MyStatus")
}

func TestGenComplexEnum_AlreadyCamelCase(t *testing.T) {
// "MyStatus" is already CamelCase. ToCamelUpper("MyStatus") == "MyStatus",
// so ByName should find it. This should always work.
idlData := makeComplexEnumIDL("MyStatus")
gen := &Generator{
idl: idlData,
options: &GeneratorOptions{Package: "test"},
}

for _, typ := range gen.idl.Types {
registerComplexEnums(typ)
}

outputFile, err := gen.genfile_types()
require.NoError(t, err, "genfile_types should not panic or error for enum named MyStatus")
require.NotNil(t, outputFile)

generatedCode := outputFile.File.GoString()
assert.Contains(t, generatedCode, "MyStatus")
}