// Copyright 2015 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Incomplete std lib sources on Android. // +build !android package importgraph_test import ( "fmt" "go/build" "sort" "strings" "testing" "golang.org/x/tools/go/buildutil" "golang.org/x/tools/refactor/importgraph" _ "crypto/hmac" // just for test, below ) const this = "golang.org/x/tools/refactor/importgraph" func TestBuild(t *testing.T) { forward, reverse, errors := importgraph.Build(&build.Default) // Test direct edges. // We throw in crypto/hmac to prove that external test files // (such as this one) are inspected. for _, p := range []string{"go/build", "testing", "crypto/hmac"} { if !forward[this][p] { t.Errorf("forward[importgraph][%s] not found", p) } if !reverse[p][this] { t.Errorf("reverse[%s][importgraph] not found", p) } } // Test non-existent direct edges for _, p := range []string{"errors", "reflect"} { if forward[this][p] { t.Errorf("unexpected: forward[importgraph][%s] found", p) } if reverse[p][this] { t.Errorf("unexpected: reverse[%s][importgraph] found", p) } } // Test vendor packages appear under their absolute names. if buildutil.AllowVendor != 0 { // hack: Go 1.6+ only if !forward["net/http"]["vendor/golang.org/x/net/http2/hpack"] { t.Errorf("forward[net/http] does not include vendor/golang.org/x/net/http2/hpack: %v", strings.Replace(fmt.Sprint(forward["net/http"]), ":true", "", -1)) } } // Test Search is reflexive. if !forward.Search(this)[this] { t.Errorf("irreflexive: forward.Search(importgraph)[importgraph] not found") } if !reverse.Search(this)[this] { t.Errorf("irrefexive: reverse.Search(importgraph)[importgraph] not found") } // Test Search is transitive. (There is no direct edge to these packages.) for _, p := range []string{"errors", "reflect", "unsafe"} { if !forward.Search(this)[p] { t.Errorf("intransitive: forward.Search(importgraph)[%s] not found", p) } if !reverse.Search(p)[this] { t.Errorf("intransitive: reverse.Search(%s)[importgraph] not found", p) } } // Test strongly-connected components. Because A's external // test package can depend on B, and vice versa, most of the // standard libraries are mutually dependent when their external // tests are considered. // // For any nodes x, y in the same SCC, y appears in the results // of both forward and reverse searches starting from x if !forward.Search("fmt")["io"] || !forward.Search("io")["fmt"] || !reverse.Search("fmt")["io"] || !reverse.Search("io")["fmt"] { t.Errorf("fmt and io are not mutually reachable despite being in the same SCC") } // debugging if false { for path, err := range errors { t.Logf("%s: %s", path, err) } printSorted := func(direction string, g importgraph.Graph, start string) { t.Log(direction) var pkgs []string for pkg := range g.Search(start) { pkgs = append(pkgs, pkg) } sort.Strings(pkgs) for _, pkg := range pkgs { t.Logf("\t%s", pkg) } } printSorted("forward", forward, this) printSorted("reverse", reverse, this) } }