198 lines
5.5 KiB
Go
198 lines
5.5 KiB
Go
package test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/pulumi/pulumi/pkg/v3/codegen/schema"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
type typeTestCase struct {
|
|
Expected map[string]interface{} `json:"expected"`
|
|
}
|
|
|
|
type typeTestImporter int
|
|
|
|
func (typeTestImporter) ImportDefaultSpec(def *schema.DefaultValue, bytes json.RawMessage) (interface{}, error) {
|
|
return bytes, nil
|
|
}
|
|
|
|
func (typeTestImporter) ImportPropertySpec(property *schema.Property, bytes json.RawMessage) (interface{}, error) {
|
|
var test typeTestCase
|
|
if err := json.Unmarshal([]byte(bytes), &test); err != nil {
|
|
return nil, err
|
|
}
|
|
return &test, nil
|
|
}
|
|
|
|
func (typeTestImporter) ImportObjectTypeSpec(object *schema.ObjectType, bytes json.RawMessage) (interface{}, error) {
|
|
return bytes, nil
|
|
}
|
|
|
|
func (typeTestImporter) ImportResourceSpec(resource *schema.Resource, bytes json.RawMessage) (interface{}, error) {
|
|
return bytes, nil
|
|
}
|
|
|
|
func (typeTestImporter) ImportFunctionSpec(function *schema.Function, bytes json.RawMessage) (interface{}, error) {
|
|
return bytes, nil
|
|
}
|
|
|
|
func (typeTestImporter) ImportPackageSpec(pkg *schema.Package, bytes json.RawMessage) (interface{}, error) {
|
|
return bytes, nil
|
|
}
|
|
|
|
type NewTypeNameGeneratorFunc func(pkg *schema.Package) TypeNameGeneratorFunc
|
|
|
|
type TypeNameGeneratorFunc func(t schema.Type) string
|
|
|
|
func TestTypeNameCodegen(t *testing.T, language string, newTypeNameGenerator NewTypeNameGeneratorFunc) { //nolint:revive
|
|
// Read in, decode, and import the schema.
|
|
schemaBytes, err := os.ReadFile(filepath.FromSlash("../internal/test/testdata/types.json"))
|
|
require.NoError(t, err)
|
|
|
|
var pkgSpec schema.PackageSpec
|
|
err = json.Unmarshal(schemaBytes, &pkgSpec)
|
|
require.NoError(t, err)
|
|
|
|
pkg, err := schema.ImportSpec(pkgSpec, map[string]schema.Language{"test": typeTestImporter(0)})
|
|
require.NoError(t, err)
|
|
|
|
typeName := newTypeNameGenerator(pkg)
|
|
|
|
if os.Getenv("PULUMI_ACCEPT") == "" {
|
|
runTests := func(where string, props []*schema.Property, inputShape bool) {
|
|
for _, p := range props {
|
|
if testCase, ok := p.Language["test"].(*typeTestCase); ok {
|
|
if expected, ok := testCase.Expected[language]; ok {
|
|
typ := p.Type
|
|
t.Run(where+"/"+p.Name, func(t *testing.T) {
|
|
var expectedName string
|
|
switch expected := expected.(type) {
|
|
case string:
|
|
expectedName = expected
|
|
case map[string]interface{}:
|
|
if inputShape {
|
|
expectedName = expected["input"].(string)
|
|
} else {
|
|
expectedName = expected["plain"].(string)
|
|
}
|
|
}
|
|
|
|
assert.Equal(t, expectedName, typeName(typ))
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
runTests("#/config", pkg.Config, false)
|
|
|
|
runTests("#/provider/properties", pkg.Provider.Properties, false)
|
|
runTests("#/provider/inputProperties", pkg.Provider.InputProperties, false)
|
|
if pkg.Provider.StateInputs != nil {
|
|
runTests("#/provider/stateInputs/properties", pkg.Provider.StateInputs.Properties, false)
|
|
}
|
|
|
|
for _, typ := range pkg.Types {
|
|
if o, ok := typ.(*schema.ObjectType); ok {
|
|
if o.IsInputShape() {
|
|
continue
|
|
}
|
|
|
|
runTests("#/types/"+o.Token+"/properties", o.Properties, false)
|
|
runTests("#/types/"+o.InputShape.Token+"/properties", o.InputShape.Properties, true)
|
|
}
|
|
}
|
|
for _, r := range pkg.Resources {
|
|
runTests("#/resources/"+r.Token+"/properties", r.Properties, false)
|
|
runTests("#/resources/"+r.Token+"/inputProperties", r.InputProperties, false)
|
|
if r.StateInputs != nil {
|
|
runTests("#/resources/"+r.Token+"/properties", r.StateInputs.Properties, false)
|
|
}
|
|
}
|
|
for _, f := range pkg.Functions {
|
|
if f.Inputs != nil {
|
|
runTests("/functions/"+f.Token+"/inputs/properties", f.Inputs.Properties, false)
|
|
}
|
|
if f.Outputs != nil {
|
|
runTests("/functions/"+f.Token+"/outputs/properties", f.Outputs.Properties, false)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
updateTests := func(props []*schema.Property) {
|
|
for _, p := range props {
|
|
testCase, _ := p.Language["test"].(*typeTestCase)
|
|
if testCase == nil {
|
|
testCase = &typeTestCase{}
|
|
p.Language["test"] = testCase
|
|
}
|
|
if testCase.Expected == nil {
|
|
testCase.Expected = map[string]interface{}{}
|
|
}
|
|
testCase.Expected[language] = typeName(p.Type)
|
|
}
|
|
}
|
|
|
|
updateTests(pkg.Config)
|
|
|
|
updateTests(pkg.Provider.Properties)
|
|
updateTests(pkg.Provider.InputProperties)
|
|
if pkg.Provider.StateInputs != nil {
|
|
updateTests(pkg.Provider.StateInputs.Properties)
|
|
}
|
|
|
|
for _, typ := range pkg.Types {
|
|
if o, ok := typ.(*schema.ObjectType); ok {
|
|
if o.IsInputShape() {
|
|
continue
|
|
}
|
|
|
|
updateTests(o.Properties)
|
|
updateTests(o.InputShape.Properties)
|
|
|
|
for i, p := range o.Properties {
|
|
testCase := p.Language["test"].(*typeTestCase)
|
|
plain := testCase.Expected[language].(string)
|
|
input := o.InputShape.Properties[i].Language["test"].(*typeTestCase).Expected[language].(string)
|
|
testCase.Expected[language] = map[string]interface{}{
|
|
"plain": plain,
|
|
"input": input,
|
|
}
|
|
o.InputShape.Properties[i].Language["test"] = testCase
|
|
}
|
|
}
|
|
}
|
|
for _, r := range pkg.Resources {
|
|
updateTests(r.Properties)
|
|
updateTests(r.InputProperties)
|
|
if r.StateInputs != nil {
|
|
updateTests(r.StateInputs.Properties)
|
|
}
|
|
}
|
|
for _, f := range pkg.Functions {
|
|
if f.Inputs != nil {
|
|
updateTests(f.Inputs.Properties)
|
|
}
|
|
if f.Outputs != nil {
|
|
updateTests(f.Outputs.Properties)
|
|
}
|
|
}
|
|
|
|
f, err := os.Create(filepath.FromSlash("../internal/test/testdata/types.json"))
|
|
require.NoError(t, err)
|
|
defer f.Close()
|
|
|
|
encoder := json.NewEncoder(f)
|
|
encoder.SetEscapeHTML(false)
|
|
encoder.SetIndent("", " ")
|
|
|
|
err = encoder.Encode(pkg)
|
|
require.NoError(t, err)
|
|
}
|