| // Copyright 2019 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. |
| |
| package frontend |
| |
| import ( |
| "context" |
| "path" |
| "testing" |
| |
| "github.com/google/go-cmp/cmp" |
| "golang.org/x/pkgsite/internal" |
| "golang.org/x/pkgsite/internal/testing/fakedatasource" |
| "golang.org/x/pkgsite/internal/testing/sample" |
| ) |
| |
| func TestFetchImportsDetails(t *testing.T) { |
| for _, test := range []struct { |
| name string |
| imports []string |
| wantDetails *ImportsDetails |
| }{ |
| { |
| name: "want imports details with standard and internal", |
| imports: []string{ |
| "pa.th/import/1", |
| sample.PackagePath, |
| "context", |
| }, |
| wantDetails: &ImportsDetails{ |
| ExternalImports: []string{"pa.th/import/1"}, |
| InternalImports: []string{sample.PackagePath}, |
| StdLib: []string{"context"}, |
| }, |
| }, |
| { |
| name: "want expected imports details with multiple", |
| imports: []string{"pa.th/import/1", "pa.th/import/2", "pa.th/import/3"}, |
| wantDetails: &ImportsDetails{ |
| ExternalImports: []string{"pa.th/import/1", "pa.th/import/2", "pa.th/import/3"}, |
| StdLib: nil, |
| }, |
| }, |
| } { |
| t.Run(test.name, func(t *testing.T) { |
| fds := fakedatasource.New() |
| |
| ctx := context.Background() |
| |
| module := sample.Module(sample.ModulePath, sample.VersionString, sample.Suffix) |
| // The first unit is the module and the second one is the package. |
| pkg := module.Units[1] |
| pkg.Imports = test.imports |
| |
| fds.MustInsertModule(ctx, module) |
| |
| got, err := fetchImportsDetails(ctx, fds, pkg.Path, pkg.ModulePath, pkg.Version) |
| if err != nil { |
| t.Fatalf("fetchImportsDetails(ctx, db, %q, %q) = %v err = %v, want %v", |
| module.Units[1].Path, module.Version, got, err, test.wantDetails) |
| } |
| |
| test.wantDetails.ModulePath = module.ModulePath |
| if diff := cmp.Diff(test.wantDetails, got); diff != "" { |
| t.Errorf("fetchImportsDetails(ctx, %q, %q) mismatch (-want +got):\n%s", module.Units[1].Path, module.Version, diff) |
| } |
| }) |
| } |
| } |
| |
| func TestFetchImportedByDetails(t *testing.T) { |
| fds := fakedatasource.New() |
| ctx := context.Background() |
| |
| newModule := func(modPath string, pkgs ...*internal.Unit) *internal.Module { |
| m := sample.Module(modPath, sample.VersionString) |
| for _, p := range pkgs { |
| sample.AddUnit(m, p) |
| } |
| return m |
| } |
| |
| pkg1 := sample.UnitForPackage("path.to/foo/bar", "path.to/foo", sample.VersionString, "bar", true) |
| pkg2 := sample.UnitForPackage("path2.to/foo/bar2", "path2.to/foo", sample.VersionString, "bar2", true) |
| pkg2.Imports = []string{pkg1.Path} |
| |
| pkg3 := sample.UnitForPackage("path3.to/foo/bar3", "path3.to/foor", sample.VersionString, "bar3", true) |
| pkg3.Imports = []string{pkg2.Path, pkg1.Path} |
| |
| testModules := []*internal.Module{ |
| newModule("path.to/foo", pkg1), |
| newModule("path2.to/foo", pkg2), |
| newModule("path3.to/foo", pkg3), |
| } |
| |
| for _, m := range testModules { |
| fds.MustInsertModule(ctx, m) |
| } |
| |
| tests := []struct { |
| pkg *internal.Unit |
| wantDetails *ImportedByDetails |
| }{ |
| { |
| pkg: pkg3, |
| wantDetails: &ImportedByDetails{ |
| NumImportedByDisplay: "0", |
| }, |
| }, |
| { |
| pkg: pkg2, |
| wantDetails: &ImportedByDetails{ |
| ImportedBy: []*Section{{Prefix: pkg3.Path, NumLines: 0}}, |
| NumImportedByDisplay: "0 (displaying 1 package, including internal and invalid packages)", |
| Total: 1, |
| }, |
| }, |
| { |
| pkg: pkg1, |
| wantDetails: &ImportedByDetails{ |
| ImportedBy: []*Section{ |
| {Prefix: pkg2.Path, NumLines: 0}, |
| {Prefix: pkg3.Path, NumLines: 0}, |
| }, |
| NumImportedByDisplay: "0 (displaying 2 packages, including internal and invalid packages)", |
| Total: 2, |
| }, |
| }, |
| } |
| |
| for _, test := range tests { |
| t.Run(test.pkg.Path, func(t *testing.T) { |
| otherVersion := newModule(path.Dir(test.pkg.Path), test.pkg) |
| otherVersion.Version = "v1.0.5" |
| pkg := otherVersion.Units[1] |
| checkFetchImportedByDetails(ctx, fds, t, pkg, test.wantDetails) |
| }) |
| } |
| } |
| |
| func TestFetchImportedByDetails_ExceedsLimit(t *testing.T) { |
| fds := fakedatasource.New() |
| ctx := context.Background() |
| |
| old := importedByLimit |
| importedByLimit = 3 |
| defer func() { importedByLimit = old }() |
| |
| m := sample.Module("m.com/a", sample.VersionString, "foo") |
| fds.MustInsertModule(ctx, m) |
| for _, mod := range []string{"m1.com/a", "m2.com/a", "m3.com/a"} { |
| m2 := sample.Module(mod, sample.VersionString, "p") |
| m2.Packages()[0].Imports = []string{"m.com/a/foo"} |
| fds.MustInsertModule(ctx, m2) |
| } |
| wantDetails := &ImportedByDetails{ |
| ModulePath: "m.com/a", |
| ImportedBy: []*Section{ |
| {Prefix: "m1.com/a/p"}, |
| {Prefix: "m2.com/a/p"}, |
| }, |
| |
| NumImportedByDisplay: "0 (displaying more than 2 packages, including internal and invalid packages)", |
| Total: 3, |
| } |
| checkFetchImportedByDetails(ctx, fds, t, m.Packages()[0], wantDetails) |
| } |
| |
| func checkFetchImportedByDetails(ctx context.Context, ds internal.DataSource, t *testing.T, pkg *internal.Unit, wantDetails *ImportedByDetails) { |
| got, err := fetchImportedByDetails(ctx, ds, pkg.Path, pkg.ModulePath) |
| if err != nil { |
| t.Fatalf("fetchImportedByDetails(ctx, db, %q) = %v err = %v, want %v", |
| pkg.Path, got, err, wantDetails) |
| } |
| wantDetails.ModulePath = pkg.ModulePath |
| if diff := cmp.Diff(wantDetails, got); diff != "" { |
| t.Errorf("fetchImportedByDetails(ctx, db, %q) mismatch (-want +got):\n%s", pkg.Path, diff) |
| } |
| } |