blob: 65232a5e64af3a10e7bd6480e818a19cd18c17cb [file]
// Copyright 2025 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 main
import (
"bytes"
"context"
"strings"
"testing"
"time"
"golang.org/x/pkgsite-metrics/internal/analysis"
"golang.org/x/pkgsite-metrics/internal/bigquery"
"google.golang.org/api/iterator"
bq "cloud.google.com/go/bigquery"
)
type mockRowIterator struct {
results []*analysis.Result
index int
}
func (it *mockRowIterator) Next(v interface{}) error {
if it.index >= len(it.results) {
return iterator.Done
}
res := it.results[it.index]
val := v.(*analysis.Result)
*val = *res
it.index++
return nil
}
type mockBQClient struct {
expectedResults []*analysis.Result
}
func (c *mockBQClient) QueryWithParams(ctx context.Context, query string, params []bq.QueryParameter) (bigquery.RowIterator, error) {
return &mockRowIterator{results: c.expectedResults}, nil
}
func (c *mockBQClient) FullTableName(tableID string) string { return "mock.table" }
func (c *mockBQClient) Close() error { return nil }
func TestFetchAndPrintResults(t *testing.T) {
mockClient := &mockBQClient{
expectedResults: []*analysis.Result{
{
ModulePath: "example.com/one",
Version: "v1.0.0",
CreatedAt: time.Now(),
Diagnostics: []*analysis.Diagnostic{
{
PackageID: "example.com/one [example.com/one.test]",
AnalyzerName: "fuzzdetect",
Category: "",
Position: "https://go-mod-viewer.appspot.com/example.com@v1.0.0/one/quorum_test.go#L59",
Message: "found the use of fuzzing",
Source: bq.NullString{StringVal: "\nfunc FuzzCalculateQuorum(f *testing.F) {\n\t// Add examples to our fuzz corpus", Valid: true},
},
},
},
},
}
var out bytes.Buffer
var lastCreatedAt time.Time
processedIDs := make(map[string]struct{})
count, err := fetchAndPrintResults(context.Background(), &out, mockClient, "fake-job-id", lastCreatedAt, processedIDs)
if err != nil {
t.Fatalf("fetchAndPrintResults failed: %v", err)
}
if count != len(mockClient.expectedResults) {
t.Errorf("expected to process %d new results, but got %d", len(mockClient.expectedResults), count)
}
got := out.String()
for _, result := range mockClient.expectedResults {
if !strings.Contains(got, result.ModulePath) {
t.Errorf("output did not contain first result; got:\n%s, wanted:%s", got, result.ModulePath)
}
if !strings.Contains(got, result.Version) {
t.Errorf("output did not contain first result; got:\n%s, wanted:%s", got, result.Version)
}
}
if len(processedIDs) != len(mockClient.expectedResults) {
t.Errorf("expected %d processed IDs, but got %d", len(mockClient.expectedResults), len(processedIDs))
}
}