Skip to content
This repository has been archived by the owner on Sep 15, 2024. It is now read-only.

Commit

Permalink
fix: use dataset plural metadata for all queries (#125)
Browse files Browse the repository at this point in the history
* fix: use dataset plural metadata for all queries

* fix: ensure subtypes are namespaced to their dataset for graphql

* fix: ensure tests handle new DataSet naming

* fix: gofmt yourself
  • Loading branch information
rawkode authored Mar 2, 2022
1 parent dee57df commit fb7a205
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 63 deletions.
4 changes: 2 additions & 2 deletions content/graphql.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func (s *Service) translateNode(node interface{}, graphqlObjects map[string]cued
dataSet, _ := s.engine.GetDataSet(node.(*cuedb.DagNode).Name)

var objectFields graphql.Fields
objectFields, err := cuedb.CueValueToGraphQlField(graphqlObjects, dataSet.GetSchemaCue())
objectFields, err := cuedb.CueValueToGraphQlField(graphqlObjects, dataSet, dataSet.GetSchemaCue())
if err != nil {
cobra.CheckErr(err)
}
Expand Down Expand Up @@ -148,7 +148,7 @@ func (s *Service) translateNode(node interface{}, graphqlObjects map[string]cued
Resolve: resolver,
}

graphqlFields[fmt.Sprintf("all%vs", dataSet.GetExternalName())] = &graphql.Field{
graphqlFields[fmt.Sprintf("all%v", dataSet.GetPluralName())] = &graphql.Field{
Type: graphql.NewList(objType),
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
dataSetName := p.Info.ReturnType.Name()
Expand Down
4 changes: 4 additions & 0 deletions internal/cuedb/dataset.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ func (d *DataSet) GetDataMapCue() string {
)
}

func (d *DataSet) GetPluralName() string {
return strings.Title(d.metadata.Plural)
}

func (d *DataSet) GetExternalName() string {
return strings.Replace(d.name, "#", "", 1)
}
Expand Down
9 changes: 5 additions & 4 deletions internal/cuedb/graphql.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type GraphQlObjectGlue struct {
Resolver func(p graphql.ResolveParams) (interface{}, error)
}

func CueValueToGraphQlField(existingObjects map[string]GraphQlObjectGlue, cueValue cue.Value) (graphql.Fields, error) {
func CueValueToGraphQlField(existingObjects map[string]GraphQlObjectGlue, dataSet DataSet, cueValue cue.Value) (graphql.Fields, error) {
fields, err := cueValue.Fields(cue.All())
if err != nil {
return nil, err
Expand All @@ -36,13 +36,14 @@ func CueValueToGraphQlField(existingObjects map[string]GraphQlObjectGlue, cueVal

switch fields.Value().IncompleteKind() {
case cue.StructKind:
subFields, err := CueValueToGraphQlField(existingObjects, fields.Value())
subFields, err := CueValueToGraphQlField(existingObjects, dataSet, fields.Value())
if err != nil {
return nil, err
}

graphQlFields[fields.Label()] = &graphql.Field{
Type: graphql.NewObject(graphql.ObjectConfig{
Name: fmt.Sprintf("%s%s", dataSet.GetExternalName(), strings.Title(fields.Label())),
Fields: subFields,
}),
}
Expand Down Expand Up @@ -94,13 +95,13 @@ func CueValueToGraphQlField(existingObjects map[string]GraphQlObjectGlue, cueVal
}

// List of non-scalar types
subFields, err := CueValueToGraphQlField(existingObjects, listOf.Value())
subFields, err := CueValueToGraphQlField(existingObjects, dataSet, listOf.Value())

// No error, so we know this is a simple value or struct
if err == nil {
graphQlFields[fields.Label()] = &graphql.Field{
Type: &graphql.List{OfType: graphql.NewObject(graphql.ObjectConfig{
Name: fields.Label(),
Name: fmt.Sprintf("%s%s", dataSet.GetExternalName(), strings.Title(fields.Label())),
Fields: subFields,
})},
}
Expand Down
146 changes: 89 additions & 57 deletions internal/cuedb/graphql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,66 +11,98 @@ import (
func TestGraphqlGeneration(t *testing.T) {
type test struct {
cueLiteral string
dataSet *DataSet
expected graphql.Fields
}

tests := []test{
{cueLiteral: "t1: string", expected: graphql.Fields{
"t1": {Type: &graphql.NonNull{OfType: graphql.String}},
}},
{cueLiteral: "t2: int", expected: graphql.Fields{
"t2": {Type: &graphql.NonNull{OfType: graphql.Int}},
}},
{cueLiteral: "t3: [...int]", expected: graphql.Fields{
"t3": {Type: &graphql.List{OfType: graphql.Int}},
}},
{cueLiteral: "t4: [...string]", expected: graphql.Fields{
"t4": {Type: &graphql.List{OfType: graphql.String}},
}},
{cueLiteral: "t5: string, t6?: int", expected: graphql.Fields{
"t5": {Type: &graphql.NonNull{OfType: graphql.String}},
"t6": {Type: graphql.Int},
}},
{cueLiteral: "{ t7: string, t8: { t9: string, t10: string} }", expected: graphql.Fields{
"t7": {Type: &graphql.NonNull{OfType: graphql.String}},
"t8": {Type: graphql.NewObject(graphql.ObjectConfig{
Fields: graphql.Fields{
"t9": {Type: &graphql.NonNull{OfType: graphql.String}},
"t10": {Type: &graphql.NonNull{OfType: graphql.String}},
},
})},
}},
{cueLiteral: "{ t11: string, t12: { t13: string, t14: string, t15: { t16: int } } }", expected: graphql.Fields{
"t11": {Type: &graphql.NonNull{OfType: graphql.String}},
"t12": {Type: graphql.NewObject(graphql.ObjectConfig{
Fields: graphql.Fields{
"t13": {Type: &graphql.NonNull{OfType: graphql.String}},
"t14": {Type: &graphql.NonNull{OfType: graphql.String}},
"t15": {Type: graphql.NewObject(graphql.ObjectConfig{
Fields: graphql.Fields{
"t16": {Type: &graphql.NonNull{OfType: graphql.Int}},
},
})},
},
})},
}},
{cueLiteral: "{ #Test: { t19: string}\nt17: string, t18: #Test }", expected: graphql.Fields{
"t17": {Type: &graphql.NonNull{OfType: graphql.String}},
"t18": {Type: graphql.NewObject(graphql.ObjectConfig{
Fields: graphql.Fields{
"t19": {Type: &graphql.NonNull{OfType: graphql.String}},
},
})},
}},
{cueLiteral: "{ #Test: { t20: string}\n t21: string, t22: [ ... #Test ] }", expected: graphql.Fields{
"t21": {Type: &graphql.NonNull{OfType: graphql.String}},
"t22": {Type: &graphql.List{OfType: graphql.NewObject(graphql.ObjectConfig{
Name: "t22",
Fields: graphql.Fields{
"t20": {Type: &graphql.NonNull{OfType: graphql.String}},
},
})}},
}},
{
dataSet: &DataSet{name: "Type"},
cueLiteral: "t1: string", expected: graphql.Fields{
"t1": {Type: &graphql.NonNull{OfType: graphql.String}},
},
},
{
dataSet: &DataSet{name: "Type"},
cueLiteral: "t2: int", expected: graphql.Fields{
"t2": {Type: &graphql.NonNull{OfType: graphql.Int}},
},
},
{
dataSet: &DataSet{name: "Type"},
cueLiteral: "t3: [...int]", expected: graphql.Fields{
"t3": {Type: &graphql.List{OfType: graphql.Int}},
},
},
{
dataSet: &DataSet{name: "Type"},
cueLiteral: "t4: [...string]", expected: graphql.Fields{
"t4": {Type: &graphql.List{OfType: graphql.String}},
},
},
{
dataSet: &DataSet{name: "Type"},
cueLiteral: "t5: string, t6?: int", expected: graphql.Fields{
"t5": {Type: &graphql.NonNull{OfType: graphql.String}},
"t6": {Type: graphql.Int},
},
},
{
dataSet: &DataSet{name: "Type"},
cueLiteral: "{ t7: string, t8: { t9: string, t10: string} }", expected: graphql.Fields{
"t7": {Type: &graphql.NonNull{OfType: graphql.String}},
"t8": {Type: graphql.NewObject(graphql.ObjectConfig{
Name: "TypeT8",
Fields: graphql.Fields{
"t9": {Type: &graphql.NonNull{OfType: graphql.String}},
"t10": {Type: &graphql.NonNull{OfType: graphql.String}},
},
})},
},
},
{
dataSet: &DataSet{name: "Type"},
cueLiteral: "{ t11: string, t12: { t13: string, t14: string, t15: { t16: int } } }", expected: graphql.Fields{
"t11": {Type: &graphql.NonNull{OfType: graphql.String}},
"t12": {Type: graphql.NewObject(graphql.ObjectConfig{
Name: "TypeT12",
Fields: graphql.Fields{
"t13": {Type: &graphql.NonNull{OfType: graphql.String}},
"t14": {Type: &graphql.NonNull{OfType: graphql.String}},
"t15": {Type: graphql.NewObject(graphql.ObjectConfig{
Name: "TypeT15",
Fields: graphql.Fields{
"t16": {Type: &graphql.NonNull{OfType: graphql.Int}},
},
})},
},
})},
},
},
{
dataSet: &DataSet{name: "Type"},
cueLiteral: "{ #Test: { t19: string}\nt17: string, t18: #Test }", expected: graphql.Fields{
"t17": {Type: &graphql.NonNull{OfType: graphql.String}},
"t18": {Type: graphql.NewObject(graphql.ObjectConfig{
Name: "TypeT18",
Fields: graphql.Fields{
"t19": {Type: &graphql.NonNull{OfType: graphql.String}},
},
})},
},
},
{
dataSet: &DataSet{name: "Type"},
cueLiteral: "{ #Test: { t20: string}\n t21: string, t22: [ ... #Test ] }", expected: graphql.Fields{
"t21": {Type: &graphql.NonNull{OfType: graphql.String}},
"t22": {Type: &graphql.List{OfType: graphql.NewObject(graphql.ObjectConfig{
Name: "TypeT22",
Fields: graphql.Fields{
"t20": {Type: &graphql.NonNull{OfType: graphql.String}},
},
})}},
},
},
// WIP
// Aim is to "flatten" disjunctions into a single struct
// {cueLiteral: "{ #A: {t23: string}\n#B: { t24?: string}\n t25: string, t26: [ ... #A | #B ] }", expected: graphql.Fields{
Expand All @@ -92,7 +124,7 @@ func TestGraphqlGeneration(t *testing.T) {

graphqlObjects := make(map[string]GraphQlObjectGlue)

graphQlObject, err := CueValueToGraphQlField(graphqlObjects, cueValue)
graphQlObject, err := CueValueToGraphQlField(graphqlObjects, *tc.dataSet, cueValue)
assert.Equal(t, nil, err)
assert.EqualValues(t, tc.expected, graphQlObject)
}
Expand Down

0 comments on commit fb7a205

Please sign in to comment.