1*1fa6dee9SAndroid Build Coastguard Worker// Copyright 2019 Google Inc. All rights reserved. 2*1fa6dee9SAndroid Build Coastguard Worker// 3*1fa6dee9SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*1fa6dee9SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*1fa6dee9SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*1fa6dee9SAndroid Build Coastguard Worker// 7*1fa6dee9SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*1fa6dee9SAndroid Build Coastguard Worker// 9*1fa6dee9SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*1fa6dee9SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*1fa6dee9SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*1fa6dee9SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*1fa6dee9SAndroid Build Coastguard Worker// limitations under the License. 14*1fa6dee9SAndroid Build Coastguard Worker 15*1fa6dee9SAndroid Build Coastguard Worker// bpdoc docs. 16*1fa6dee9SAndroid Build Coastguard Workerpackage bpdoc 17*1fa6dee9SAndroid Build Coastguard Worker 18*1fa6dee9SAndroid Build Coastguard Workerimport ( 19*1fa6dee9SAndroid Build Coastguard Worker "html/template" 20*1fa6dee9SAndroid Build Coastguard Worker "reflect" 21*1fa6dee9SAndroid Build Coastguard Worker "runtime" 22*1fa6dee9SAndroid Build Coastguard Worker "testing" 23*1fa6dee9SAndroid Build Coastguard Worker 24*1fa6dee9SAndroid Build Coastguard Worker "github.com/google/blueprint" 25*1fa6dee9SAndroid Build Coastguard Worker "github.com/google/blueprint/proptools" 26*1fa6dee9SAndroid Build Coastguard Worker) 27*1fa6dee9SAndroid Build Coastguard Worker 28*1fa6dee9SAndroid Build Coastguard Workertype factoryFn func() (blueprint.Module, []interface{}) 29*1fa6dee9SAndroid Build Coastguard Worker 30*1fa6dee9SAndroid Build Coastguard Worker// foo docs. 31*1fa6dee9SAndroid Build Coastguard Workerfunc fooFactory() (blueprint.Module, []interface{}) { 32*1fa6dee9SAndroid Build Coastguard Worker return nil, []interface{}{&props{}} 33*1fa6dee9SAndroid Build Coastguard Worker} 34*1fa6dee9SAndroid Build Coastguard Worker 35*1fa6dee9SAndroid Build Coastguard Worker// bar docs. 36*1fa6dee9SAndroid Build Coastguard Workerfunc barFactory() (blueprint.Module, []interface{}) { 37*1fa6dee9SAndroid Build Coastguard Worker return nil, []interface{}{&complexProps{}} 38*1fa6dee9SAndroid Build Coastguard Worker} 39*1fa6dee9SAndroid Build Coastguard Worker 40*1fa6dee9SAndroid Build Coastguard Workertype structToNest struct { 41*1fa6dee9SAndroid Build Coastguard Worker E string 42*1fa6dee9SAndroid Build Coastguard Worker} 43*1fa6dee9SAndroid Build Coastguard Worker 44*1fa6dee9SAndroid Build Coastguard Workertype StructToEmbed struct { 45*1fa6dee9SAndroid Build Coastguard Worker Nested_in_embedded structToNest 46*1fa6dee9SAndroid Build Coastguard Worker 47*1fa6dee9SAndroid Build Coastguard Worker // F string 48*1fa6dee9SAndroid Build Coastguard Worker F string 49*1fa6dee9SAndroid Build Coastguard Worker} 50*1fa6dee9SAndroid Build Coastguard Worker 51*1fa6dee9SAndroid Build Coastguard Workertype otherStructToNest struct { 52*1fa6dee9SAndroid Build Coastguard Worker G string 53*1fa6dee9SAndroid Build Coastguard Worker} 54*1fa6dee9SAndroid Build Coastguard Worker 55*1fa6dee9SAndroid Build Coastguard Workertype OtherStructToEmbed struct { 56*1fa6dee9SAndroid Build Coastguard Worker Nested_in_other_embedded otherStructToNest 57*1fa6dee9SAndroid Build Coastguard Worker 58*1fa6dee9SAndroid Build Coastguard Worker // F string 59*1fa6dee9SAndroid Build Coastguard Worker H string 60*1fa6dee9SAndroid Build Coastguard Worker} 61*1fa6dee9SAndroid Build Coastguard Worker 62*1fa6dee9SAndroid Build Coastguard Workertype StructWithEmbedded struct { 63*1fa6dee9SAndroid Build Coastguard Worker StructToEmbed 64*1fa6dee9SAndroid Build Coastguard Worker} 65*1fa6dee9SAndroid Build Coastguard Worker 66*1fa6dee9SAndroid Build Coastguard Worker// for bpdoc_test.go 67*1fa6dee9SAndroid Build Coastguard Workertype complexProps struct { 68*1fa6dee9SAndroid Build Coastguard Worker A string 69*1fa6dee9SAndroid Build Coastguard Worker B_mutated string `blueprint:"mutated"` 70*1fa6dee9SAndroid Build Coastguard Worker 71*1fa6dee9SAndroid Build Coastguard Worker Nested struct { 72*1fa6dee9SAndroid Build Coastguard Worker C string 73*1fa6dee9SAndroid Build Coastguard Worker D_mutated string `blueprint:"mutated"` 74*1fa6dee9SAndroid Build Coastguard Worker } 75*1fa6dee9SAndroid Build Coastguard Worker 76*1fa6dee9SAndroid Build Coastguard Worker Nested_struct structToNest 77*1fa6dee9SAndroid Build Coastguard Worker 78*1fa6dee9SAndroid Build Coastguard Worker Struct_has_embed StructWithEmbedded 79*1fa6dee9SAndroid Build Coastguard Worker 80*1fa6dee9SAndroid Build Coastguard Worker OtherStructToEmbed 81*1fa6dee9SAndroid Build Coastguard Worker 82*1fa6dee9SAndroid Build Coastguard Worker List_of_ints []int 83*1fa6dee9SAndroid Build Coastguard Worker 84*1fa6dee9SAndroid Build Coastguard Worker List_of_nested []structToNest 85*1fa6dee9SAndroid Build Coastguard Worker 86*1fa6dee9SAndroid Build Coastguard Worker Configurable_bool proptools.Configurable[bool] 87*1fa6dee9SAndroid Build Coastguard Worker} 88*1fa6dee9SAndroid Build Coastguard Worker 89*1fa6dee9SAndroid Build Coastguard Worker// props docs. 90*1fa6dee9SAndroid Build Coastguard Workertype props struct { 91*1fa6dee9SAndroid Build Coastguard Worker // A docs. 92*1fa6dee9SAndroid Build Coastguard Worker A string 93*1fa6dee9SAndroid Build Coastguard Worker} 94*1fa6dee9SAndroid Build Coastguard Worker 95*1fa6dee9SAndroid Build Coastguard Worker// for properties_test.go 96*1fa6dee9SAndroid Build Coastguard Workertype tagTestProps struct { 97*1fa6dee9SAndroid Build Coastguard Worker A string `tag1:"a,b" tag2:"c"` 98*1fa6dee9SAndroid Build Coastguard Worker B string `tag1:"a,c"` 99*1fa6dee9SAndroid Build Coastguard Worker C string `tag1:"b,c"` 100*1fa6dee9SAndroid Build Coastguard Worker 101*1fa6dee9SAndroid Build Coastguard Worker D struct { 102*1fa6dee9SAndroid Build Coastguard Worker E string `tag1:"a,b" tag2:"c"` 103*1fa6dee9SAndroid Build Coastguard Worker F string `tag1:"a,c"` 104*1fa6dee9SAndroid Build Coastguard Worker G string `tag1:"b,c"` 105*1fa6dee9SAndroid Build Coastguard Worker } `tag1:"b,c"` 106*1fa6dee9SAndroid Build Coastguard Worker} 107*1fa6dee9SAndroid Build Coastguard Worker 108*1fa6dee9SAndroid Build Coastguard Workervar pkgPath string 109*1fa6dee9SAndroid Build Coastguard Workervar pkgFiles map[string][]string 110*1fa6dee9SAndroid Build Coastguard Workervar moduleTypeNameFactories map[string]reflect.Value 111*1fa6dee9SAndroid Build Coastguard Workervar moduleTypeNamePropertyStructs map[string][]interface{} 112*1fa6dee9SAndroid Build Coastguard Worker 113*1fa6dee9SAndroid Build Coastguard Workerfunc init() { 114*1fa6dee9SAndroid Build Coastguard Worker pc, filename, _, _ := runtime.Caller(0) 115*1fa6dee9SAndroid Build Coastguard Worker fn := runtime.FuncForPC(pc) 116*1fa6dee9SAndroid Build Coastguard Worker 117*1fa6dee9SAndroid Build Coastguard Worker var err error 118*1fa6dee9SAndroid Build Coastguard Worker pkgPath, err = funcNameToPkgPath(fn.Name()) 119*1fa6dee9SAndroid Build Coastguard Worker if err != nil { 120*1fa6dee9SAndroid Build Coastguard Worker panic(err) 121*1fa6dee9SAndroid Build Coastguard Worker } 122*1fa6dee9SAndroid Build Coastguard Worker 123*1fa6dee9SAndroid Build Coastguard Worker pkgFiles = map[string][]string{ 124*1fa6dee9SAndroid Build Coastguard Worker pkgPath: {filename}, 125*1fa6dee9SAndroid Build Coastguard Worker } 126*1fa6dee9SAndroid Build Coastguard Worker 127*1fa6dee9SAndroid Build Coastguard Worker factories := map[string]factoryFn{"foo": fooFactory, "bar": barFactory} 128*1fa6dee9SAndroid Build Coastguard Worker 129*1fa6dee9SAndroid Build Coastguard Worker moduleTypeNameFactories = make(map[string]reflect.Value, len(factories)) 130*1fa6dee9SAndroid Build Coastguard Worker moduleTypeNamePropertyStructs = make(map[string][]interface{}, len(factories)) 131*1fa6dee9SAndroid Build Coastguard Worker for name, factory := range factories { 132*1fa6dee9SAndroid Build Coastguard Worker moduleTypeNameFactories[name] = reflect.ValueOf(factory) 133*1fa6dee9SAndroid Build Coastguard Worker _, structs := factory() 134*1fa6dee9SAndroid Build Coastguard Worker moduleTypeNamePropertyStructs[name] = structs 135*1fa6dee9SAndroid Build Coastguard Worker } 136*1fa6dee9SAndroid Build Coastguard Worker} 137*1fa6dee9SAndroid Build Coastguard Worker 138*1fa6dee9SAndroid Build Coastguard Workerfunc TestModuleTypeDocs(t *testing.T) { 139*1fa6dee9SAndroid Build Coastguard Worker r := NewReader(pkgFiles) 140*1fa6dee9SAndroid Build Coastguard Worker for m := range moduleTypeNameFactories { 141*1fa6dee9SAndroid Build Coastguard Worker mt, err := r.ModuleType(m+"_module", moduleTypeNameFactories[m]) 142*1fa6dee9SAndroid Build Coastguard Worker if err != nil { 143*1fa6dee9SAndroid Build Coastguard Worker t.Fatal(err) 144*1fa6dee9SAndroid Build Coastguard Worker } 145*1fa6dee9SAndroid Build Coastguard Worker 146*1fa6dee9SAndroid Build Coastguard Worker expectedText := template.HTML(m + " docs.\n\n") 147*1fa6dee9SAndroid Build Coastguard Worker if mt.Text != expectedText { 148*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("unexpected docs %q", mt.Text) 149*1fa6dee9SAndroid Build Coastguard Worker } 150*1fa6dee9SAndroid Build Coastguard Worker 151*1fa6dee9SAndroid Build Coastguard Worker if mt.PkgPath != pkgPath { 152*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("expected pkgpath %q, got %q", pkgPath, mt.PkgPath) 153*1fa6dee9SAndroid Build Coastguard Worker } 154*1fa6dee9SAndroid Build Coastguard Worker } 155*1fa6dee9SAndroid Build Coastguard Worker} 156*1fa6dee9SAndroid Build Coastguard Worker 157*1fa6dee9SAndroid Build Coastguard Workerfunc TestPropertyStruct(t *testing.T) { 158*1fa6dee9SAndroid Build Coastguard Worker r := NewReader(pkgFiles) 159*1fa6dee9SAndroid Build Coastguard Worker ps, err := r.PropertyStruct(pkgPath, "props", reflect.ValueOf(props{A: "B"})) 160*1fa6dee9SAndroid Build Coastguard Worker if err != nil { 161*1fa6dee9SAndroid Build Coastguard Worker t.Fatal(err) 162*1fa6dee9SAndroid Build Coastguard Worker } 163*1fa6dee9SAndroid Build Coastguard Worker 164*1fa6dee9SAndroid Build Coastguard Worker if ps.Text != "props docs.\n" { 165*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("unexpected docs %q", ps.Text) 166*1fa6dee9SAndroid Build Coastguard Worker } 167*1fa6dee9SAndroid Build Coastguard Worker if len(ps.Properties) != 1 { 168*1fa6dee9SAndroid Build Coastguard Worker t.Fatalf("want 1 property, got %d", len(ps.Properties)) 169*1fa6dee9SAndroid Build Coastguard Worker } 170*1fa6dee9SAndroid Build Coastguard Worker 171*1fa6dee9SAndroid Build Coastguard Worker if ps.Properties[0].Name != "a" || ps.Properties[0].Text != "A docs.\n\n" || ps.Properties[0].Default != "B" { 172*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("unexpected property docs %q %q %q", 173*1fa6dee9SAndroid Build Coastguard Worker ps.Properties[0].Name, ps.Properties[0].Text, ps.Properties[0].Default) 174*1fa6dee9SAndroid Build Coastguard Worker } 175*1fa6dee9SAndroid Build Coastguard Worker} 176*1fa6dee9SAndroid Build Coastguard Worker 177*1fa6dee9SAndroid Build Coastguard Workerfunc TestPackage(t *testing.T) { 178*1fa6dee9SAndroid Build Coastguard Worker r := NewReader(pkgFiles) 179*1fa6dee9SAndroid Build Coastguard Worker pkg, err := r.Package(pkgPath) 180*1fa6dee9SAndroid Build Coastguard Worker if err != nil { 181*1fa6dee9SAndroid Build Coastguard Worker t.Fatal(err) 182*1fa6dee9SAndroid Build Coastguard Worker } 183*1fa6dee9SAndroid Build Coastguard Worker 184*1fa6dee9SAndroid Build Coastguard Worker if pkg.Text != "bpdoc docs.\n" { 185*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("unexpected docs %q", pkg.Text) 186*1fa6dee9SAndroid Build Coastguard Worker } 187*1fa6dee9SAndroid Build Coastguard Worker} 188*1fa6dee9SAndroid Build Coastguard Worker 189*1fa6dee9SAndroid Build Coastguard Workerfunc TestFuncToPkgPath(t *testing.T) { 190*1fa6dee9SAndroid Build Coastguard Worker tests := []struct { 191*1fa6dee9SAndroid Build Coastguard Worker f string 192*1fa6dee9SAndroid Build Coastguard Worker want string 193*1fa6dee9SAndroid Build Coastguard Worker }{ 194*1fa6dee9SAndroid Build Coastguard Worker { 195*1fa6dee9SAndroid Build Coastguard Worker f: "github.com/google/blueprint/bootstrap.Main", 196*1fa6dee9SAndroid Build Coastguard Worker want: "github.com/google/blueprint/bootstrap", 197*1fa6dee9SAndroid Build Coastguard Worker }, 198*1fa6dee9SAndroid Build Coastguard Worker { 199*1fa6dee9SAndroid Build Coastguard Worker f: "android/soong/android.GenruleFactory", 200*1fa6dee9SAndroid Build Coastguard Worker want: "android/soong/android", 201*1fa6dee9SAndroid Build Coastguard Worker }, 202*1fa6dee9SAndroid Build Coastguard Worker { 203*1fa6dee9SAndroid Build Coastguard Worker f: "android/soong/android.ModuleFactoryAdapter.func1", 204*1fa6dee9SAndroid Build Coastguard Worker want: "android/soong/android", 205*1fa6dee9SAndroid Build Coastguard Worker }, 206*1fa6dee9SAndroid Build Coastguard Worker { 207*1fa6dee9SAndroid Build Coastguard Worker f: "main.Main", 208*1fa6dee9SAndroid Build Coastguard Worker want: "main", 209*1fa6dee9SAndroid Build Coastguard Worker }, 210*1fa6dee9SAndroid Build Coastguard Worker } 211*1fa6dee9SAndroid Build Coastguard Worker for _, tt := range tests { 212*1fa6dee9SAndroid Build Coastguard Worker t.Run(tt.f, func(t *testing.T) { 213*1fa6dee9SAndroid Build Coastguard Worker got, err := funcNameToPkgPath(tt.f) 214*1fa6dee9SAndroid Build Coastguard Worker if err != nil { 215*1fa6dee9SAndroid Build Coastguard Worker t.Fatal(err) 216*1fa6dee9SAndroid Build Coastguard Worker } 217*1fa6dee9SAndroid Build Coastguard Worker if got != tt.want { 218*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("funcNameToPkgPath(%v) = %v, want %v", tt.f, got, tt.want) 219*1fa6dee9SAndroid Build Coastguard Worker } 220*1fa6dee9SAndroid Build Coastguard Worker }) 221*1fa6dee9SAndroid Build Coastguard Worker } 222*1fa6dee9SAndroid Build Coastguard Worker} 223