Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial tests coverage for golang jenny #16

Merged
merged 1 commit into from
Sep 19, 2023
Merged
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
7 changes: 7 additions & 0 deletions internal/ast/compiler/disjunctions.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package compiler

import (
"sort"
"strings"

"github.com/grafana/cog/internal/ast"
Expand Down Expand Up @@ -41,6 +42,12 @@ func (pass *DisjunctionToType) processFile(file *ast.File) (*ast.File, error) {
newObjects = append(newObjects, obj)
}

// Since newly created objects are temporarily stored in a map, we need to
// sort them to have a deterministic output.
sort.SliceStable(newObjects, func(i, j int) bool {
return newObjects[i].Name < newObjects[j].Name
})

return &ast.File{
Package: file.Package,
Definitions: append(processedObjects, newObjects...),
Expand Down
10 changes: 3 additions & 7 deletions internal/jennies/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,13 @@ type LanguageTarget struct {

func All() map[string]LanguageTarget {
targets := map[string]LanguageTarget{
// Compiler passes should not have side effects, but they do.
"go": {
Jennies: golang.Jennies(),
CompilerPasses: []compiler.Pass{
&compiler.AnonymousEnumToExplicitType{},
&compiler.DisjunctionToType{},
},
Jennies: golang.Jennies(),
CompilerPasses: golang.CompilerPasses(),
},
"typescript": {
Jennies: typescript.Jennies(),
CompilerPasses: nil,
CompilerPasses: typescript.CompilerPasses(),
},
}

Expand Down
8 changes: 8 additions & 0 deletions internal/jennies/golang/jennies.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package golang
import (
"github.com/grafana/codejen"
"github.com/grafana/cog/internal/ast"
"github.com/grafana/cog/internal/ast/compiler"
"github.com/grafana/cog/internal/jennies/tools"
"github.com/grafana/cog/internal/veneers"
)
Expand All @@ -29,3 +30,10 @@ func Jennies() *codejen.JennyList[[]*ast.File] {

return targets
}

func CompilerPasses() []compiler.Pass {
return []compiler.Pass{
&compiler.AnonymousEnumToExplicitType{},
&compiler.DisjunctionToType{},
}
}
37 changes: 8 additions & 29 deletions internal/jennies/golang/rawtypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,6 @@ func (jenny RawTypes) formatObject(def ast.Object) ([]byte, error) {
}

switch def.Type.Kind {
case ast.KindStruct:
buffer.WriteString(fmt.Sprintf("type %s ", defName))
buffer.WriteString(formatStructBody(def.Type.AsStruct(), ""))
buffer.WriteString("\n")
case ast.KindEnum:
buffer.WriteString(jenny.formatEnumDef(def))
case ast.KindScalar:
Expand All @@ -77,16 +73,16 @@ func (jenny RawTypes) formatObject(def ast.Object) ([]byte, error) {
if scalarType.Value != nil {
buffer.WriteString(fmt.Sprintf("const %s = %s", defName, formatScalar(scalarType.Value)))
} else {
buffer.WriteString(fmt.Sprintf("type %s %s", defName, scalarType.ScalarKind))
buffer.WriteString(fmt.Sprintf("type %s %s", defName, formatType(def.Type, true, "")))
}
case ast.KindMap:
case ast.KindMap, ast.KindRef, ast.KindArray, ast.KindStruct:
buffer.WriteString(fmt.Sprintf("type %s %s", defName, formatType(def.Type, true, "")))
case ast.KindRef:
buffer.WriteString(fmt.Sprintf("type %s %s", defName, def.Type.AsRef().ReferredType))
default:
return nil, fmt.Errorf("unhandled type def kind: %s", def.Type.Kind)
}

buffer.WriteString("\n")

return []byte(buffer.String()), nil
}

Expand Down Expand Up @@ -116,9 +112,9 @@ func (jenny RawTypes) veneer(veneerType string, def ast.Object) (string, error)
if tmpl == nil {
tmpl = templates.Lookup(fmt.Sprintf("types.%s.go.tmpl", veneerType))
}
// If not, something went wrong.
// If not, then there's nothing to do.
if tmpl == nil {
return "", fmt.Errorf("veneer '%s' not found", veneerType)
return "", nil
}

buf := bytes.Buffer{}
Expand Down Expand Up @@ -180,10 +176,6 @@ func formatType(def ast.Type, fieldIsRequired bool, typesPkg string) string {
return "any"
}

if def.Kind == ast.KindDisjunction {
return formatDisjunction(def.AsDisjunction(), typesPkg)
}

if def.Kind == ast.KindArray {
return formatArray(def.AsArray(), typesPkg)
}
Expand Down Expand Up @@ -215,16 +207,12 @@ func formatType(def ast.Type, fieldIsRequired bool, typesPkg string) string {
return typeName
}

if def.Kind == ast.KindEnum {
return "enum here"
}

// anonymous struct
if def.Kind == ast.KindStruct {
return formatStructBody(def.AsStruct(), typesPkg)
}

// FIXME: we shouldn't be here
// FIXME: we should never be here
return "unknown"
}

Expand All @@ -241,15 +229,6 @@ func formatMap(def ast.MapType, typesPkg string) string {
return fmt.Sprintf("map[%s]%s", keyTypeString, valueTypeString)
}

func formatDisjunction(def ast.DisjunctionType, typesPkg string) string {
subTypes := make([]string, 0, len(def.Branches))
for _, subType := range def.Branches {
subTypes = append(subTypes, formatType(subType, true, typesPkg))
}

return fmt.Sprintf("disjunction<%s>", strings.Join(subTypes, " | "))
}

func formatScalar(val any) string {
if list, ok := val.([]any); ok {
items := make([]string, 0, len(list))
Expand All @@ -258,7 +237,7 @@ func formatScalar(val any) string {
items = append(items, formatScalar(item))
}

// TODO: we can't assume a list of strings
// FIXME: this is wrong, we can't just assume a list of strings.
return fmt.Sprintf("[]string{%s}", strings.Join(items, ", "))
}

Expand Down
41 changes: 41 additions & 0 deletions internal/jennies/golang/rawtypes_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package golang

import (
"testing"

"github.com/grafana/cog/internal/ast"
"github.com/grafana/cog/internal/txtartest"
"github.com/stretchr/testify/require"
)

func TestRawTypes_Generate(t *testing.T) {
test := txtartest.TxTarTest{
Root: "../../../testdata/jennies/rawtypes",
Name: "jennies/GoRawTypes",
}

jenny := RawTypes{}
compilerPasses := CompilerPasses()

test.Run(t, func(tc *txtartest.Test) {
req := require.New(tc)

var err error
processedAsts := []*ast.File{tc.TypesIR()}

// We run the compiler passes defined fo Go since without them, we
// might not be able to translate some of the IR's semantics into Go.
// Example: disjunctions.
for _, compilerPass := range compilerPasses {
processedAsts, err = compilerPass.Process(processedAsts)
req.NoError(err)
}

req.Len(processedAsts, 1, "we somehow got more ast.File than we put in")

files, err := jenny.Generate(processedAsts[0])
req.NoError(err)

tc.WriteFiles(files)
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,14 @@
// Grafana.
func (resource {{ .def.Name|formatIdentifier }}) MarshalJSON() ([]byte, error) {
if resource.ValString != nil {
var buf bytes.Buffer
buf.WriteRune('"')
buf.WriteString(*resource.ValString)
buf.WriteRune('"')
return buf.Bytes(), nil
}

return strconv.AppendBool([]byte{}, *resource.ValBool), nil
}
var buf bytes.Buffer
buf.WriteRune('"')
buf.WriteString(*resource.ValString)
buf.WriteRune('"')
return buf.Bytes(), nil
}

// MarshalIndentJSON renders the resource as indented JSON
// which your configuration management tool of choice can then feed into
// Grafana.
func (resource {{ .def.Name|formatIdentifier }}) MarshalIndentJSON() ([]byte, error) {
return json.MarshalIndent(resource, "", " ")
return strconv.AppendBool([]byte{}, *resource.ValBool), nil
}

func (resource {{ .def.Name|formatIdentifier }}) UnmarshalJSON(raw []byte) error {
Expand All @@ -32,13 +25,13 @@ func (resource {{ .def.Name|formatIdentifier }}) UnmarshalJSON(raw []byte) error
)
if raw[0] != '"' {
if bytes.Equal(raw, []byte("true")) {
yup := true
yup := true
resource.ValBool = &yup
return nil
}
if bytes.Equal(raw, []byte("false")) {
nope := false
resource.ValBool = &nope
nope := false
resource.ValBool = &nope
return nil
}
return errors.New("bad boolean value provided")
Expand All @@ -49,3 +42,4 @@ func (resource {{ .def.Name|formatIdentifier }}) UnmarshalJSON(raw []byte) error
resource.ValString = &tmp
return nil
}

6 changes: 0 additions & 6 deletions internal/jennies/golang/veneers/types.json_marshal.go.tmpl

This file was deleted.

5 changes: 5 additions & 0 deletions internal/jennies/typescript/jennies.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package typescript
import (
"github.com/grafana/codejen"
"github.com/grafana/cog/internal/ast"
"github.com/grafana/cog/internal/ast/compiler"
"github.com/grafana/cog/internal/jennies/tools"
"github.com/grafana/cog/internal/veneers"
)
Expand Down Expand Up @@ -31,3 +32,7 @@ func Jennies() *codejen.JennyList[[]*ast.File] {

return targets
}

func CompilerPasses() []compiler.Pass {
return nil
}
15 changes: 15 additions & 0 deletions internal/jennies/typescript/rawtypes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package typescript
import (
"testing"

"github.com/grafana/cog/internal/ast"
"github.com/grafana/cog/internal/txtartest"
"github.com/stretchr/testify/require"
)
Expand All @@ -14,10 +15,24 @@ func TestRawTypes_Generate(t *testing.T) {
}

jenny := RawTypes{}
compilerPasses := CompilerPasses()

test.Run(t, func(tc *txtartest.Test) {
req := require.New(tc)

var err error
processedAsts := []*ast.File{tc.TypesIR()}

// We run the compiler passes defined fo Go since without them, we
// might not be able to translate some of the IR's semantics into Go.
// Example: disjunctions.
for _, compilerPass := range compilerPasses {
processedAsts, err = compilerPass.Process(processedAsts)
req.NoError(err)
}

req.Len(processedAsts, 1, "we somehow got more ast.File than we put in")

files, err := jenny.Generate(tc.TypesIR())
req.NoError(err)

Expand Down
15 changes: 15 additions & 0 deletions testdata/jennies/rawtypes/arrays.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,18 @@ export type ArrayOfRefs = SomeStruct[];

export type ArrayOfArrayOfNumbers = number[][];

-- out/jennies/GoRawTypes --
== types/arrays/types_gen.go
package types

// List of tags, maybe?
type ArrayOfStrings []string

type SomeStruct struct {
FieldAny any `json:"FieldAny"`
}

type ArrayOfRefs []SomeStruct

type ArrayOfArrayOfNumbers [][]int64

Loading