blob: 67ad783ea18346de979b1e3dc2ba50dce536de14 [file] [log] [blame]
package bpdoc
import (
"fmt"
"reflect"
"testing"
)
type propInfo struct {
name string
typ string
}
type parentProps struct {
A string
Child *childProps
Mutated *mutatedProps `blueprint:"mutated"`
}
type childProps struct {
B int
Child *grandchildProps
}
type grandchildProps struct {
C bool
}
type mutatedProps struct {
D int
}
func TestNestedPropertyStructs(t *testing.T) {
parent := parentProps{Child: &childProps{Child: &grandchildProps{}}, Mutated: &mutatedProps{}}
allStructs := nestedPropertyStructs(reflect.ValueOf(parent))
// mutated shouldn't be found because it's a mutated property.
expected := []string{"child", "child.child"}
if len(allStructs) != len(expected) {
t.Fatalf("expected %d structs, got %d, all entries: %v",
len(expected), len(allStructs), allStructs)
}
got := []string{}
for _, s := range allStructs {
got = append(got, s.nestPoint)
}
if !reflect.DeepEqual(got, expected) {
t.Errorf("Expected nested properties:\n\t %q,\n but got\n\t %q", expected, got)
}
}
func TestAllPackages(t *testing.T) {
packages, err := AllPackages(pkgFiles, moduleTypeNameFactories, moduleTypeNamePropertyStructs)
if err != nil {
t.Fatalf("expected nil error for AllPackages(%v, %v, %v), got %s", pkgFiles, moduleTypeNameFactories, moduleTypeNamePropertyStructs, err)
}
if numPackages := len(packages); numPackages != 1 {
t.Errorf("Expected %d package, got %d packages %v instead", len(pkgFiles), numPackages, packages)
}
pkg := packages[0]
expectedProps := map[string][]propInfo{
"bar": []propInfo{
propInfo{
name: "a",
typ: "string",
},
propInfo{
name: "nested",
typ: "",
},
propInfo{
name: "nested.c",
typ: "string",
},
propInfo{
name: "nested_struct",
typ: "structToNest",
},
propInfo{
name: "nested_struct.e",
typ: "string",
},
propInfo{
name: "struct_has_embed",
typ: "StructWithEmbedded",
},
propInfo{
name: "struct_has_embed.nested_in_embedded",
typ: "structToNest",
},
propInfo{
name: "struct_has_embed.nested_in_embedded.e",
typ: "string",
},
propInfo{
name: "struct_has_embed.f",
typ: "string",
},
propInfo{
name: "list_of_ints",
typ: "list of int",
},
propInfo{
name: "list_of_nested",
typ: "list of structToNest",
},
propInfo{
name: "nested_in_other_embedded",
typ: "otherStructToNest",
},
propInfo{
name: "nested_in_other_embedded.g",
typ: "string",
},
propInfo{
name: "h",
typ: "string",
},
},
"foo": []propInfo{
propInfo{
name: "a",
typ: "string",
},
},
}
for _, m := range pkg.ModuleTypes {
foundProps := []propInfo{}
for _, p := range m.PropertyStructs {
nestedProps, errs := findAllProperties("", p.Properties)
foundProps = append(foundProps, nestedProps...)
for _, err := range errs {
t.Errorf("%s", err)
}
}
if wanted, ok := expectedProps[m.Name]; ok {
if !reflect.DeepEqual(foundProps, wanted) {
t.Errorf("For %s, expected\n\t %q,\nbut got\n\t %q", m.Name, wanted, foundProps)
}
}
}
}
func findAllProperties(prefix string, properties []Property) ([]propInfo, []error) {
foundProps := []propInfo{}
errs := []error{}
for _, p := range properties {
prop := propInfo{
name: prefix + p.Name,
typ: p.Type,
}
foundProps = append(foundProps, prop)
if hasTag(p.Tag, "blueprint", "mutated") {
err := fmt.Errorf("Property %s has `blueprint:\"mutated\" tag but should have been excluded.", p.Name)
errs = append(errs, err)
}
nestedProps, nestedErrs := findAllProperties(prefix+p.Name+".", p.Properties)
foundProps = append(foundProps, nestedProps...)
errs = append(errs, nestedErrs...)
}
return foundProps, errs
}