1*1fa6dee9SAndroid Build Coastguard Workerpackage bpdoc 2*1fa6dee9SAndroid Build Coastguard Worker 3*1fa6dee9SAndroid Build Coastguard Workerimport ( 4*1fa6dee9SAndroid Build Coastguard Worker "fmt" 5*1fa6dee9SAndroid Build Coastguard Worker "reflect" 6*1fa6dee9SAndroid Build Coastguard Worker "testing" 7*1fa6dee9SAndroid Build Coastguard Worker) 8*1fa6dee9SAndroid Build Coastguard Worker 9*1fa6dee9SAndroid Build Coastguard Workertype propInfo struct { 10*1fa6dee9SAndroid Build Coastguard Worker name string 11*1fa6dee9SAndroid Build Coastguard Worker typ string 12*1fa6dee9SAndroid Build Coastguard Worker} 13*1fa6dee9SAndroid Build Coastguard Worker 14*1fa6dee9SAndroid Build Coastguard Workertype parentProps struct { 15*1fa6dee9SAndroid Build Coastguard Worker A string 16*1fa6dee9SAndroid Build Coastguard Worker 17*1fa6dee9SAndroid Build Coastguard Worker Child *childProps 18*1fa6dee9SAndroid Build Coastguard Worker 19*1fa6dee9SAndroid Build Coastguard Worker Mutated *mutatedProps `blueprint:"mutated"` 20*1fa6dee9SAndroid Build Coastguard Worker} 21*1fa6dee9SAndroid Build Coastguard Worker 22*1fa6dee9SAndroid Build Coastguard Workertype childProps struct { 23*1fa6dee9SAndroid Build Coastguard Worker B int 24*1fa6dee9SAndroid Build Coastguard Worker 25*1fa6dee9SAndroid Build Coastguard Worker Child *grandchildProps 26*1fa6dee9SAndroid Build Coastguard Worker} 27*1fa6dee9SAndroid Build Coastguard Worker 28*1fa6dee9SAndroid Build Coastguard Workertype grandchildProps struct { 29*1fa6dee9SAndroid Build Coastguard Worker C bool 30*1fa6dee9SAndroid Build Coastguard Worker} 31*1fa6dee9SAndroid Build Coastguard Worker 32*1fa6dee9SAndroid Build Coastguard Workertype mutatedProps struct { 33*1fa6dee9SAndroid Build Coastguard Worker D int 34*1fa6dee9SAndroid Build Coastguard Worker} 35*1fa6dee9SAndroid Build Coastguard Worker 36*1fa6dee9SAndroid Build Coastguard Workerfunc TestNestedPropertyStructs(t *testing.T) { 37*1fa6dee9SAndroid Build Coastguard Worker parent := parentProps{Child: &childProps{Child: &grandchildProps{}}, Mutated: &mutatedProps{}} 38*1fa6dee9SAndroid Build Coastguard Worker 39*1fa6dee9SAndroid Build Coastguard Worker allStructs := nestedPropertyStructs(reflect.ValueOf(parent)) 40*1fa6dee9SAndroid Build Coastguard Worker 41*1fa6dee9SAndroid Build Coastguard Worker // mutated shouldn't be found because it's a mutated property. 42*1fa6dee9SAndroid Build Coastguard Worker expected := []string{"child", "child.child"} 43*1fa6dee9SAndroid Build Coastguard Worker if len(allStructs) != len(expected) { 44*1fa6dee9SAndroid Build Coastguard Worker t.Fatalf("expected %d structs, got %d, all entries: %v", 45*1fa6dee9SAndroid Build Coastguard Worker len(expected), len(allStructs), allStructs) 46*1fa6dee9SAndroid Build Coastguard Worker } 47*1fa6dee9SAndroid Build Coastguard Worker got := []string{} 48*1fa6dee9SAndroid Build Coastguard Worker for _, s := range allStructs { 49*1fa6dee9SAndroid Build Coastguard Worker got = append(got, s.nestPoint) 50*1fa6dee9SAndroid Build Coastguard Worker } 51*1fa6dee9SAndroid Build Coastguard Worker 52*1fa6dee9SAndroid Build Coastguard Worker if !reflect.DeepEqual(got, expected) { 53*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("Expected nested properties:\n\t %q,\n but got\n\t %q", expected, got) 54*1fa6dee9SAndroid Build Coastguard Worker } 55*1fa6dee9SAndroid Build Coastguard Worker} 56*1fa6dee9SAndroid Build Coastguard Worker 57*1fa6dee9SAndroid Build Coastguard Workerfunc TestAllPackages(t *testing.T) { 58*1fa6dee9SAndroid Build Coastguard Worker packages, err := AllPackages(pkgFiles, moduleTypeNameFactories, moduleTypeNamePropertyStructs) 59*1fa6dee9SAndroid Build Coastguard Worker if err != nil { 60*1fa6dee9SAndroid Build Coastguard Worker t.Fatalf("expected nil error for AllPackages(%v, %v, %v), got %s", pkgFiles, moduleTypeNameFactories, moduleTypeNamePropertyStructs, err) 61*1fa6dee9SAndroid Build Coastguard Worker } 62*1fa6dee9SAndroid Build Coastguard Worker 63*1fa6dee9SAndroid Build Coastguard Worker if numPackages := len(packages); numPackages != 1 { 64*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("Expected %d package, got %d packages %v instead", len(pkgFiles), numPackages, packages) 65*1fa6dee9SAndroid Build Coastguard Worker } 66*1fa6dee9SAndroid Build Coastguard Worker 67*1fa6dee9SAndroid Build Coastguard Worker pkg := packages[0] 68*1fa6dee9SAndroid Build Coastguard Worker 69*1fa6dee9SAndroid Build Coastguard Worker expectedProps := map[string][]propInfo{ 70*1fa6dee9SAndroid Build Coastguard Worker "bar": []propInfo{ 71*1fa6dee9SAndroid Build Coastguard Worker propInfo{ 72*1fa6dee9SAndroid Build Coastguard Worker name: "a", 73*1fa6dee9SAndroid Build Coastguard Worker typ: "string", 74*1fa6dee9SAndroid Build Coastguard Worker }, 75*1fa6dee9SAndroid Build Coastguard Worker propInfo{ 76*1fa6dee9SAndroid Build Coastguard Worker name: "nested", 77*1fa6dee9SAndroid Build Coastguard Worker typ: "", 78*1fa6dee9SAndroid Build Coastguard Worker }, 79*1fa6dee9SAndroid Build Coastguard Worker propInfo{ 80*1fa6dee9SAndroid Build Coastguard Worker name: "nested.c", 81*1fa6dee9SAndroid Build Coastguard Worker typ: "string", 82*1fa6dee9SAndroid Build Coastguard Worker }, 83*1fa6dee9SAndroid Build Coastguard Worker propInfo{ 84*1fa6dee9SAndroid Build Coastguard Worker name: "nested_struct", 85*1fa6dee9SAndroid Build Coastguard Worker typ: "structToNest", 86*1fa6dee9SAndroid Build Coastguard Worker }, 87*1fa6dee9SAndroid Build Coastguard Worker propInfo{ 88*1fa6dee9SAndroid Build Coastguard Worker name: "nested_struct.e", 89*1fa6dee9SAndroid Build Coastguard Worker typ: "string", 90*1fa6dee9SAndroid Build Coastguard Worker }, 91*1fa6dee9SAndroid Build Coastguard Worker propInfo{ 92*1fa6dee9SAndroid Build Coastguard Worker name: "struct_has_embed", 93*1fa6dee9SAndroid Build Coastguard Worker typ: "StructWithEmbedded", 94*1fa6dee9SAndroid Build Coastguard Worker }, 95*1fa6dee9SAndroid Build Coastguard Worker propInfo{ 96*1fa6dee9SAndroid Build Coastguard Worker name: "struct_has_embed.nested_in_embedded", 97*1fa6dee9SAndroid Build Coastguard Worker typ: "structToNest", 98*1fa6dee9SAndroid Build Coastguard Worker }, 99*1fa6dee9SAndroid Build Coastguard Worker propInfo{ 100*1fa6dee9SAndroid Build Coastguard Worker name: "struct_has_embed.nested_in_embedded.e", 101*1fa6dee9SAndroid Build Coastguard Worker typ: "string", 102*1fa6dee9SAndroid Build Coastguard Worker }, 103*1fa6dee9SAndroid Build Coastguard Worker propInfo{ 104*1fa6dee9SAndroid Build Coastguard Worker name: "struct_has_embed.f", 105*1fa6dee9SAndroid Build Coastguard Worker typ: "string", 106*1fa6dee9SAndroid Build Coastguard Worker }, 107*1fa6dee9SAndroid Build Coastguard Worker propInfo{ 108*1fa6dee9SAndroid Build Coastguard Worker name: "list_of_ints", 109*1fa6dee9SAndroid Build Coastguard Worker typ: "list of int", 110*1fa6dee9SAndroid Build Coastguard Worker }, 111*1fa6dee9SAndroid Build Coastguard Worker propInfo{ 112*1fa6dee9SAndroid Build Coastguard Worker name: "list_of_nested", 113*1fa6dee9SAndroid Build Coastguard Worker typ: "list of structToNest", 114*1fa6dee9SAndroid Build Coastguard Worker }, 115*1fa6dee9SAndroid Build Coastguard Worker propInfo{ 116*1fa6dee9SAndroid Build Coastguard Worker name: "configurable_bool", 117*1fa6dee9SAndroid Build Coastguard Worker typ: "configurable bool", 118*1fa6dee9SAndroid Build Coastguard Worker }, 119*1fa6dee9SAndroid Build Coastguard Worker propInfo{ 120*1fa6dee9SAndroid Build Coastguard Worker name: "nested_in_other_embedded", 121*1fa6dee9SAndroid Build Coastguard Worker typ: "otherStructToNest", 122*1fa6dee9SAndroid Build Coastguard Worker }, 123*1fa6dee9SAndroid Build Coastguard Worker propInfo{ 124*1fa6dee9SAndroid Build Coastguard Worker name: "nested_in_other_embedded.g", 125*1fa6dee9SAndroid Build Coastguard Worker typ: "string", 126*1fa6dee9SAndroid Build Coastguard Worker }, 127*1fa6dee9SAndroid Build Coastguard Worker propInfo{ 128*1fa6dee9SAndroid Build Coastguard Worker name: "h", 129*1fa6dee9SAndroid Build Coastguard Worker typ: "string", 130*1fa6dee9SAndroid Build Coastguard Worker }, 131*1fa6dee9SAndroid Build Coastguard Worker }, 132*1fa6dee9SAndroid Build Coastguard Worker "foo": []propInfo{ 133*1fa6dee9SAndroid Build Coastguard Worker propInfo{ 134*1fa6dee9SAndroid Build Coastguard Worker name: "a", 135*1fa6dee9SAndroid Build Coastguard Worker typ: "string", 136*1fa6dee9SAndroid Build Coastguard Worker }, 137*1fa6dee9SAndroid Build Coastguard Worker }, 138*1fa6dee9SAndroid Build Coastguard Worker } 139*1fa6dee9SAndroid Build Coastguard Worker 140*1fa6dee9SAndroid Build Coastguard Worker for _, m := range pkg.ModuleTypes { 141*1fa6dee9SAndroid Build Coastguard Worker foundProps := []propInfo{} 142*1fa6dee9SAndroid Build Coastguard Worker 143*1fa6dee9SAndroid Build Coastguard Worker for _, p := range m.PropertyStructs { 144*1fa6dee9SAndroid Build Coastguard Worker nestedProps, errs := findAllProperties("", p.Properties) 145*1fa6dee9SAndroid Build Coastguard Worker foundProps = append(foundProps, nestedProps...) 146*1fa6dee9SAndroid Build Coastguard Worker for _, err := range errs { 147*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("%s", err) 148*1fa6dee9SAndroid Build Coastguard Worker } 149*1fa6dee9SAndroid Build Coastguard Worker } 150*1fa6dee9SAndroid Build Coastguard Worker if wanted, ok := expectedProps[m.Name]; ok { 151*1fa6dee9SAndroid Build Coastguard Worker if !reflect.DeepEqual(foundProps, wanted) { 152*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("For %s, expected\n\t %q,\nbut got\n\t %q", m.Name, wanted, foundProps) 153*1fa6dee9SAndroid Build Coastguard Worker } 154*1fa6dee9SAndroid Build Coastguard Worker } 155*1fa6dee9SAndroid Build Coastguard Worker } 156*1fa6dee9SAndroid Build Coastguard Worker} 157*1fa6dee9SAndroid Build Coastguard Worker 158*1fa6dee9SAndroid Build Coastguard Workerfunc findAllProperties(prefix string, properties []Property) ([]propInfo, []error) { 159*1fa6dee9SAndroid Build Coastguard Worker foundProps := []propInfo{} 160*1fa6dee9SAndroid Build Coastguard Worker errs := []error{} 161*1fa6dee9SAndroid Build Coastguard Worker for _, p := range properties { 162*1fa6dee9SAndroid Build Coastguard Worker prop := propInfo{ 163*1fa6dee9SAndroid Build Coastguard Worker name: prefix + p.Name, 164*1fa6dee9SAndroid Build Coastguard Worker typ: p.Type, 165*1fa6dee9SAndroid Build Coastguard Worker } 166*1fa6dee9SAndroid Build Coastguard Worker foundProps = append(foundProps, prop) 167*1fa6dee9SAndroid Build Coastguard Worker if hasTag(p.Tag, "blueprint", "mutated") { 168*1fa6dee9SAndroid Build Coastguard Worker err := fmt.Errorf("Property %s has `blueprint:\"mutated\" tag but should have been excluded.", p.Name) 169*1fa6dee9SAndroid Build Coastguard Worker errs = append(errs, err) 170*1fa6dee9SAndroid Build Coastguard Worker } 171*1fa6dee9SAndroid Build Coastguard Worker 172*1fa6dee9SAndroid Build Coastguard Worker nestedProps, nestedErrs := findAllProperties(prefix+p.Name+".", p.Properties) 173*1fa6dee9SAndroid Build Coastguard Worker foundProps = append(foundProps, nestedProps...) 174*1fa6dee9SAndroid Build Coastguard Worker errs = append(errs, nestedErrs...) 175*1fa6dee9SAndroid Build Coastguard Worker } 176*1fa6dee9SAndroid Build Coastguard Worker return foundProps, errs 177*1fa6dee9SAndroid Build Coastguard Worker} 178