func TestParseOk(t *testing.T) { pwd, err := os.Getwd() if err != nil { t.Fatal(err) } par := parse.New("github.com/cloudfoundry-incubator/guardian", filepath.Join(pwd, "../fixtures/guardian"), true) graph, err := par.Parse() if err != nil { t.Fail() } // Check the packages are correct. s := graph.Packages() expected := guardianPackages if !s.Equals(expected) { t.Errorf("Expected %v to equal %v", s, expected) } // Check a representative sample of imports are correct. guardianGraphSample.Walk(func(p Pkg, i PSet) { j, ok := graph.Imports(p) if !ok { t.Fail() } if !i.Equals(j) { t.Errorf("The imports of %s were %v rather than the expected %v", p, j, i) } }) }
func TestParseBadPackage(t *testing.T) { pwd, err := os.Getwd() if err != nil { t.Fatal(err) } par := parse.New("github.com/cloudfoundry-incubator/grauniad", filepath.Join(pwd, "../fixtures/guardian"), true) _, err = par.Parse() expectedErrPrefix := "lstat " expectedErrSuffix := "github.com/cloudfoundry-incubator/grauniad: no such file or directory" actualErrString := err.Error() if !strings.HasPrefix(actualErrString, expectedErrPrefix) || !strings.HasSuffix(actualErrString, expectedErrSuffix) { t.Errorf("Expected error %s...%s but got %s", expectedErrPrefix, expectedErrSuffix, err) } }
func analyse(c *cli.Context) { pc := parse.New(c.Args().Get(0), os.Getenv("GOPATH"), false) // TODO: add "include tests" flag imports, err := pc.Parse() if err != nil { panic(err) } imports.Walk(func(p Pkg, i PSet) { fmt.Printf("Package %s imports: %v.\n", pc.ShortName(p), pc.ShortNames(i)) }) // Analyse self-contained packages. imports.Packages().Walk(func(p Pkg) { escape := false pc.Walk(p, func(q Pkg, qi PSet) { qi.Walk(func(i Pkg) { if !p.HasSubpackage(i) { escape = true } }) }) if !escape { fmt.Printf("%s is self-contained\n", pc.ShortName(p)) } }) // Compute scoped fan-out of each package. fanOut := make(map[Pkg]int, 1) imports.Walk(func(p Pkg, i PSet) { fanOut[p] = i.Size() }) // Compute scoped fan-in of each package. fanIn := make(map[Pkg]int, 1) imports.Walk(func(_ Pkg, i PSet) { i.Walk(func(q Pkg) { fanIn[q] = fanIn[q] + 1 }) }) // Compute scoped instability of each package. instab := make(map[Pkg]float32, 1) imports.Walk(func(p Pkg, i PSet) { instab[p] = instability(fanIn[p], fanOut[p]) fmt.Printf("%s has fan-in %d, fan-out %d, and instability %.2f\n", pc.ShortName(p), fanIn[p], fanOut[p], instab[p]) }) // Check stable dependencies principle violations. imports.Walk(func(p Pkg, i PSet) { i.Walk(func(q Pkg) { if instab[q] > instab[p] { fmt.Printf("%s depends on the less stable %s\n", pc.ShortName(p), pc.ShortName(q)) } }) }) // Detect direct dependency cycles. imports.Walk(func(p Pkg, imp PSet) { imp.Walk(func(i Pkg) { if q, ok := imports.Imports(i); ok { if q.Contains(p) { fmt.Printf("Direct dependency cycle between %s and %s\n", pc.ShortName(p), pc.ShortName(i)) } } }) }) }