Skip to content

Commit

Permalink
add singleton examples and error when not tuple
Browse files Browse the repository at this point in the history
  • Loading branch information
gcheadle-vmware committed Jan 12, 2022
1 parent 0d735e8 commit b9549aa
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 18 deletions.
55 changes: 55 additions & 0 deletions pkg/cmd/template/schema_author_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,61 @@ schema.yml:

assertFails(t, filesToProcess, expectedErr, opts)
})
t.Run("is not a tuple", func(t *testing.T) {
schemaYAML := `#@data/values-schema
---
#@schema/examples "example value"
key: val
`
expectedErr := `
Invalid schema
==============
syntax error in @schema/examples annotation
schema.yml:
|
3 | #@schema/examples "example value"
4 | key: val
|
= found: non tuple in @schema/examples (by schema.yml:3)
= expected: tuple with optional string description and required example value
= hint: use a trailing comma to construct tuple with a single value. e.g. ('example value',)
`

filesToProcess := files.NewSortedFiles([]*files.File{
files.MustNewFileFromSource(files.NewBytesSource("schema.yml", []byte(schemaYAML))),
})

assertFails(t, filesToProcess, expectedErr, opts)
})
t.Run("is an empty tuple", func(t *testing.T) {
schemaYAML := `#@data/values-schema
---
#@schema/examples ()
key: val
`
expectedErr := `
Invalid schema
==============
syntax error in @schema/examples annotation
schema.yml:
|
3 | #@schema/examples ()
4 | key: val
|
= found: empty tuple in @schema/examples (by schema.yml:3)
= expected: tuple with optional string description and required example value
`

filesToProcess := files.NewSortedFiles([]*files.File{
files.MustNewFileFromSource(files.NewBytesSource("schema.yml", []byte(schemaYAML))),
})

assertFails(t, filesToProcess, expectedErr, opts)
})
t.Run("has more than two args in an example", func(t *testing.T) {
schemaYAML := `#@data/values-schema
---
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/template/schema_inspect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ db_conn:
#@schema/examples ("hostname example description", "localhost")
#@schema/desc "The hostname"
hostname: ""
#@schema/examples (8080)
#@schema/examples (8080,)
port: 0
#@schema/examples ("timeout example description", 4.2), ("another timeout ex desc", 5)
timeout: 1.0
Expand Down
55 changes: 38 additions & 17 deletions pkg/schema/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ func NewExampleAnnotation(ann template.NodeAnnotation, pos *filepos.Position) (*
found: fmt.Sprintf("missing value in @%v (by %v)", AnnotationExamples, ann.Position.AsCompactString()),
}
}
//TODO: how can we prevent input like: #@schema/examples 8080, 8000, 10

var descriptions []string
var examples []interface{}
for _, example := range ann.Args {
Expand All @@ -236,33 +236,54 @@ func NewExampleAnnotation(ann template.NodeAnnotation, pos *filepos.Position) (*
var err error

if exampleTuple, ok := example.(starlark.Tuple); ok {
if len(exampleTuple) > 2 {
switch len(exampleTuple) {
case 0:
return nil, schemaAssertionError{
annPositions: []*filepos.Position{ann.Position},
position: pos,
description: fmt.Sprintf("syntax error in @%v annotation", AnnotationExamples),
expected: fmt.Sprintf("no more than 2 arguments per tuple. e.g. @%v ('description', exampleValue())", AnnotationExamples),
found: fmt.Sprintf("%v arguments in @%v (by %v)", len(exampleTuple), AnnotationExamples, ann.Position.AsCompactString()),
expected: fmt.Sprintf("tuple with optional string description and required example value"),
found: fmt.Sprintf("empty tuple in @%v (by %v)", AnnotationExamples, ann.Position.AsCompactString()),
}
}
exampleDescription, err = core.NewStarlarkValue(exampleTuple[0]).AsString()
if err != nil {
case 1:
exampleYAML, err = core.NewStarlarkValue(exampleTuple[0]).AsGoValue()
if err != nil {
panic(err)
}
case 2:
exampleDescription, err = core.NewStarlarkValue(exampleTuple[0]).AsString()
if err != nil {
return nil, schemaAssertionError{
annPositions: []*filepos.Position{ann.Position},
position: pos,
description: fmt.Sprintf("syntax error in @%v annotation", AnnotationExamples),
expected: fmt.Sprintf("string"),
found: fmt.Sprintf("Non-string value in @%v (by %v)", AnnotationExamples, ann.Position.AsCompactString()),
hints: []string{fmt.Sprintf("@%v optionally accepts a string description as the first argument in a tuple", AnnotationExamples)},
}
}
exampleYAML, err = core.NewStarlarkValue(exampleTuple[1]).AsGoValue()
if err != nil {
panic(err)
}
default:
return nil, schemaAssertionError{
annPositions: []*filepos.Position{ann.Position},
position: pos,
description: fmt.Sprintf("syntax error in @%v annotation", AnnotationExamples),
expected: fmt.Sprintf("string"),
found: fmt.Sprintf("Non-string value in @%v (by %v)", AnnotationExamples, ann.Position.AsCompactString()),
hints: []string{fmt.Sprintf("@%v optionally accepts a string description as the first argument in a tuple", AnnotationExamples)},
expected: fmt.Sprintf("no more than 2 arguments per tuple. e.g. @%v ('description', exampleValue())", AnnotationExamples),
found: fmt.Sprintf("%v arguments in @%v (by %v)", len(exampleTuple), AnnotationExamples, ann.Position.AsCompactString()),
}
}
example = exampleTuple[1]
}

exampleYAML, err = core.NewStarlarkValue(example).AsGoValue()
if err != nil {
//at this point the annotation is processed, and the Starlark evaluated
panic(err)
} else {
return nil, schemaAssertionError{
annPositions: []*filepos.Position{ann.Position},
position: pos,
description: fmt.Sprintf("syntax error in @%v annotation", AnnotationExamples),
expected: fmt.Sprintf("tuple with optional string description and required example value"),
found: fmt.Sprintf("non tuple in @%v (by %v)", AnnotationExamples, ann.Position.AsCompactString()),
hints: []string{"use a trailing comma to construct tuple with a single value. e.g. ('example value',)"},
}
}
descriptions = append(descriptions, exampleDescription)
examples = append(examples, yamlmeta.NewASTFromInterfaceWithPosition(exampleYAML, pos))
Expand Down

0 comments on commit b9549aa

Please sign in to comment.