diff --git a/client/cache.go b/client/cache.go
deleted file mode 100644
index a9a540f..0000000
--- a/client/cache.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2021 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 client
-
-import (
-	"time"
-
-	"golang.org/x/vulndb/osv"
-)
-
-// Cache interface for vuln DB caching.
-type Cache interface {
-	ReadIndex(string) (osv.DBIndex, time.Time, error)
-	WriteIndex(string, osv.DBIndex, time.Time) error
-	ReadEntries(string, string) ([]*osv.Entry, error)
-	WriteEntries(string, string, []*osv.Entry) error
-}
diff --git a/client/client.go b/client/client.go
deleted file mode 100644
index 7cd18c8..0000000
--- a/client/client.go
+++ /dev/null
@@ -1,389 +0,0 @@
-// Copyright 2021 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 client provides an interface for accessing vulnerability
-// databases, via either HTTP or local filesystem access.
-//
-// The expected database layout is the same for both HTTP and local
-// databases. The database  index is located at the root of the
-// database, and contains a list of all of the vulnerable modules
-// documented in the databse and the time the most recent vulnerability
-// was added. The index file is called indx.json, and has the
-// following format:
-//
-//   map[string]time.Time (osv.DBIndex)
-//
-// Each vulnerable module is represented by an individual JSON file
-// which contains all of the vulnerabilities in that module. The path
-// for each module file is simply the import path of the module,
-// i.e. vulnerabilities in golang.org/x/crypto are contained in the
-// golang.org/x/crypto.json file. The per-module JSON files have
-// the following format:
-//
-//   []osv.Entry
-//
-// A single client.Client can be used to access multiple vulnerability
-// databases. When looking up vulnerable module each database is
-// consulted, and results are merged together.
-//
-// TODO: allow filtering private module, possibly at a database level?
-// (e.g. I may want to use multiple databases, but only lookup a specific
-// module in a subset of them)
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"net/url"
-	"os"
-	"path/filepath"
-	"sort"
-	"strings"
-	"time"
-
-	"golang.org/x/vulndb/internal"
-	"golang.org/x/vulndb/internal/derrors"
-	"golang.org/x/vulndb/osv"
-)
-
-// Client interface for fetching vulnerabilities based on module path or ID.
-type Client interface {
-	// GetByModule returns the entries that affect the given module path.
-	// It returns (nil, nil) if there are none.
-	GetByModule(string) ([]*osv.Entry, error)
-
-	// GetByID returns the entry with the given ID, or (nil, nil) if there isn't
-	// one.
-	GetByID(string) (*osv.Entry, error)
-
-	// ListIDs returns the IDs of all entries in the database.
-	ListIDs() ([]string, error)
-
-	unexported() // ensures that adding a method won't break users
-}
-
-type source interface {
-	Client
-	Index() (osv.DBIndex, error)
-}
-
-type localSource struct {
-	dir string
-}
-
-func (*localSource) unexported() {}
-
-func (ls *localSource) GetByModule(module string) (_ []*osv.Entry, err error) {
-	defer derrors.Wrap(&err, "GetByModule(%q)", module)
-	content, err := ioutil.ReadFile(filepath.Join(ls.dir, module+".json"))
-	if os.IsNotExist(err) {
-		return nil, nil
-	} else if err != nil {
-		return nil, err
-	}
-	var e []*osv.Entry
-	if err = json.Unmarshal(content, &e); err != nil {
-		return nil, err
-	}
-	return e, nil
-}
-
-func (ls *localSource) GetByID(id string) (_ *osv.Entry, err error) {
-	defer derrors.Wrap(&err, "GetByID(%q)", id)
-	content, err := ioutil.ReadFile(filepath.Join(ls.dir, internal.IDDirectory, id+".json"))
-	if os.IsNotExist(err) {
-		return nil, nil
-	} else if err != nil {
-		return nil, err
-	}
-	var e osv.Entry
-	if err = json.Unmarshal(content, &e); err != nil {
-		return nil, err
-	}
-	return &e, nil
-}
-
-func (ls *localSource) ListIDs() (_ []string, err error) {
-	defer derrors.Wrap(&err, "ListIDs()")
-	content, err := ioutil.ReadFile(filepath.Join(ls.dir, internal.IDDirectory, "index.json"))
-	if err != nil {
-		return nil, err
-	}
-	var ids []string
-	if err := json.Unmarshal(content, &ids); err != nil {
-		return nil, err
-	}
-	return ids, nil
-}
-
-func (ls *localSource) Index() (_ osv.DBIndex, err error) {
-	defer derrors.Wrap(&err, "Index()")
-	var index osv.DBIndex
-	b, err := ioutil.ReadFile(filepath.Join(ls.dir, "index.json"))
-	if err != nil {
-		return nil, err
-	}
-	if err = json.Unmarshal(b, &index); err != nil {
-		return nil, err
-	}
-	return index, nil
-}
-
-type httpSource struct {
-	url    string // the base URI of the source (without trailing "/"). e.g. https://vuln.golang.org
-	c      *http.Client
-	cache  Cache
-	dbName string
-}
-
-func (hs *httpSource) Index() (_ osv.DBIndex, err error) {
-	defer derrors.Wrap(&err, "Index()")
-
-	var cachedIndex osv.DBIndex
-	var cachedIndexRetrieved *time.Time
-
-	if hs.cache != nil {
-		index, retrieved, err := hs.cache.ReadIndex(hs.dbName)
-		if err != nil {
-			return nil, err
-		}
-
-		cachedIndex = index
-		if cachedIndex != nil {
-			if time.Since(retrieved) < time.Hour*2 {
-				return cachedIndex, nil
-			}
-
-			cachedIndexRetrieved = &retrieved
-		}
-	}
-
-	req, err := http.NewRequest("GET", fmt.Sprintf("%s/index.json", hs.url), nil)
-	if err != nil {
-		return nil, err
-	}
-	if cachedIndexRetrieved != nil {
-		req.Header.Add("If-Modified-Since", cachedIndexRetrieved.Format(http.TimeFormat))
-	}
-	resp, err := hs.c.Do(req)
-	if err != nil {
-		return nil, err
-	}
-	defer resp.Body.Close()
-	if cachedIndexRetrieved != nil && resp.StatusCode == http.StatusNotModified {
-		// If status has not been modified, this is equivalent to returning the
-		// same index. We update the timestamp so the next cache index read does
-		// not require a roundtrip to the server.
-		if err = hs.cache.WriteIndex(hs.dbName, cachedIndex, time.Now()); err != nil {
-			return nil, err
-		}
-		return cachedIndex, nil
-	}
-	if resp.StatusCode != http.StatusOK {
-		return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
-	}
-	b, err := ioutil.ReadAll(resp.Body)
-	if err != nil {
-		return nil, err
-	}
-	var index osv.DBIndex
-	if err = json.Unmarshal(b, &index); err != nil {
-		return nil, err
-	}
-
-	if hs.cache != nil {
-		if err = hs.cache.WriteIndex(hs.dbName, index, time.Now()); err != nil {
-			return nil, err
-		}
-	}
-
-	return index, nil
-}
-
-func (*httpSource) unexported() {}
-
-func (hs *httpSource) GetByModule(module string) (_ []*osv.Entry, err error) {
-	defer derrors.Wrap(&err, "GetByModule(%q)", module)
-
-	index, err := hs.Index()
-	if err != nil {
-		return nil, err
-	}
-
-	lastModified, present := index[module]
-	if !present {
-		return nil, nil
-	}
-
-	if hs.cache != nil {
-		if cached, err := hs.cache.ReadEntries(hs.dbName, module); err != nil {
-			return nil, err
-		} else if len(cached) != 0 {
-			var stale bool
-			for _, c := range cached {
-				if c.Modified.Before(lastModified) {
-					stale = true
-					break
-				}
-			}
-			if !stale {
-				return cached, nil
-			}
-		}
-	}
-
-	content, err := hs.readBody(fmt.Sprintf("%s/%s.json", hs.url, module))
-	if err != nil || content == nil {
-		return nil, err
-	}
-	var e []*osv.Entry
-	// TODO: we may want to check that the returned entries actually match
-	// the module we asked about, so that the cache cannot be poisoned
-	if err = json.Unmarshal(content, &e); err != nil {
-		return nil, err
-	}
-
-	if hs.cache != nil {
-		if err := hs.cache.WriteEntries(hs.dbName, module, e); err != nil {
-			return nil, err
-		}
-	}
-	return e, nil
-}
-
-func (hs *httpSource) GetByID(id string) (_ *osv.Entry, err error) {
-	defer derrors.Wrap(&err, "GetByID(%q)", id)
-
-	content, err := hs.readBody(fmt.Sprintf("%s/%s/%s.json", hs.url, internal.IDDirectory, id))
-	if err != nil || content == nil {
-		return nil, err
-	}
-	var e osv.Entry
-	if err := json.Unmarshal(content, &e); err != nil {
-		return nil, err
-	}
-	return &e, nil
-}
-
-func (hs *httpSource) ListIDs() (_ []string, err error) {
-	defer derrors.Wrap(&err, "ListIDs()")
-
-	content, err := hs.readBody(fmt.Sprintf("%s/%s/index.json", hs.url, internal.IDDirectory))
-	if err != nil {
-		return nil, err
-	}
-	var ids []string
-	if err := json.Unmarshal(content, &ids); err != nil {
-		return nil, err
-	}
-	return ids, nil
-}
-
-func (hs *httpSource) readBody(url string) ([]byte, error) {
-	resp, err := hs.c.Get(url)
-	if err != nil {
-		return nil, err
-	}
-	defer resp.Body.Close()
-	if resp.StatusCode == http.StatusNotFound {
-		return nil, nil
-	}
-	// might want this to be a LimitedReader
-	return ioutil.ReadAll(resp.Body)
-}
-
-type client struct {
-	sources []source
-}
-
-type Options struct {
-	HTTPClient *http.Client
-	HTTPCache  Cache
-}
-
-func NewClient(sources []string, opts Options) (_ Client, err error) {
-	defer derrors.Wrap(&err, "NewClient(%v, opts)", sources)
-	c := &client{}
-	for _, uri := range sources {
-		uri = strings.TrimRight(uri, "/")
-		// should parse the URI out here instead of in there
-		switch {
-		case strings.HasPrefix(uri, "http://") || strings.HasPrefix(uri, "https://"):
-			hs := &httpSource{url: uri}
-			url, err := url.Parse(uri)
-			if err != nil {
-				return nil, err
-			}
-			hs.dbName = url.Hostname()
-			if opts.HTTPCache != nil {
-				hs.cache = opts.HTTPCache
-			}
-			if opts.HTTPClient != nil {
-				hs.c = opts.HTTPClient
-			} else {
-				hs.c = new(http.Client)
-			}
-			c.sources = append(c.sources, hs)
-		case strings.HasPrefix(uri, "file://"):
-			c.sources = append(c.sources, &localSource{dir: strings.TrimPrefix(uri, "file://")})
-		default:
-			return nil, fmt.Errorf("source %q has unsupported scheme", uri)
-		}
-	}
-	return c, nil
-}
-
-func (*client) unexported() {}
-
-func (c *client) GetByModule(module string) (_ []*osv.Entry, err error) {
-	defer derrors.Wrap(&err, "GetByModule(%q)", module)
-	var entries []*osv.Entry
-	// probably should be parallelized
-	for _, s := range c.sources {
-		e, err := s.GetByModule(module)
-		if err != nil {
-			return nil, err // be failure tolerant?
-		}
-		entries = append(entries, e...)
-	}
-	return entries, nil
-}
-
-func (c *client) GetByID(id string) (_ *osv.Entry, err error) {
-	defer derrors.Wrap(&err, "GetByID(%q)", id)
-	for _, s := range c.sources {
-		entry, err := s.GetByID(id)
-		if err != nil {
-			return nil, err // be failure tolerant?
-		}
-		if entry != nil {
-			return entry, nil
-		}
-	}
-	return nil, nil
-}
-
-// ListIDs returns the union of the IDs from all sources,
-// sorted lexically.
-func (c *client) ListIDs() (_ []string, err error) {
-	defer derrors.Wrap(&err, "ListIDs()")
-	idSet := map[string]bool{}
-	for _, s := range c.sources {
-		ids, err := s.ListIDs()
-		if err != nil {
-			return nil, err
-		}
-		for _, id := range ids {
-			idSet[id] = true
-		}
-	}
-	var ids []string
-	for id := range idSet {
-		ids = append(ids, id)
-	}
-	sort.Strings(ids)
-	return ids, nil
-}
diff --git a/client/client_test.go b/client/client_test.go
deleted file mode 100644
index f4f0cb0..0000000
--- a/client/client_test.go
+++ /dev/null
@@ -1,360 +0,0 @@
-// Copyright 2021 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 client
-
-import (
-	"encoding/json"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"net/http"
-	"net/http/httptest"
-	"net/url"
-	"os"
-	"path"
-	"reflect"
-	"runtime"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"golang.org/x/vulndb/internal"
-	"golang.org/x/vulndb/osv"
-)
-
-var (
-	testVuln = `
-	{"ID":"ID","Package":{"Name":"golang.org/example/one","Ecosystem":"go"}, "Summary":"",
-	 "Severity":2,"Affects":{"Ranges":[{"Type":"SEMVER","Introduced":"","Fixed":"v2.2.0"}]},
-	 "ecosystem_specific":{"Symbols":["some_symbol_1"]
-	}}`
-
-	testVulns = "[" + testVuln + "]"
-)
-
-var (
-	// index containing timestamps for package in testVuln.
-	index string = `{
-	"golang.org/example/one": "2020-03-09T10:00:00.81362141-07:00"
-	}`
-	// index of IDs
-	idIndex string = `["ID"]`
-)
-
-// testCache for testing purposes
-type testCache struct {
-	indexMap   map[string]osv.DBIndex
-	indexStamp map[string]time.Time
-	vulnMap    map[string]map[string][]*osv.Entry
-}
-
-func freshTestCache() *testCache {
-	return &testCache{
-		indexMap:   make(map[string]osv.DBIndex),
-		indexStamp: make(map[string]time.Time),
-		vulnMap:    make(map[string]map[string][]*osv.Entry),
-	}
-}
-
-func (tc *testCache) ReadIndex(db string) (osv.DBIndex, time.Time, error) {
-	index, ok := tc.indexMap[db]
-	if !ok {
-		return nil, time.Time{}, nil
-	}
-	stamp, ok := tc.indexStamp[db]
-	if !ok {
-		return nil, time.Time{}, nil
-	}
-	return index, stamp, nil
-}
-
-func (tc *testCache) WriteIndex(db string, index osv.DBIndex, stamp time.Time) error {
-	tc.indexMap[db] = index
-	tc.indexStamp[db] = stamp
-	return nil
-}
-
-func (tc *testCache) ReadEntries(db, module string) ([]*osv.Entry, error) {
-	mMap, ok := tc.vulnMap[db]
-	if !ok {
-		return nil, nil
-	}
-	return mMap[module], nil
-}
-
-func (tc *testCache) WriteEntries(db, module string, entries []*osv.Entry) error {
-	mMap, ok := tc.vulnMap[db]
-	if !ok {
-		mMap = make(map[string][]*osv.Entry)
-		tc.vulnMap[db] = mMap
-	}
-	mMap[module] = append(mMap[module], entries...)
-	return nil
-}
-
-// cachedTestVuln returns a function creating a local cache
-// for db with `dbName` with a version of testVuln where
-// Summary="cached" and LastModified happened after entry
-// in the `index` for the same pkg.
-func cachedTestVuln(dbName string) Cache {
-	c := freshTestCache()
-	e := &osv.Entry{
-		ID:       "ID1",
-		Details:  "cached",
-		Modified: time.Now(),
-	}
-	c.WriteEntries(dbName, "golang.org/example/one", []*osv.Entry{e})
-	return c
-}
-
-// createDirAndFile creates a directory `dir` if such directory does
-// not exist and creates a `file` with `content` in the directory.
-func createDirAndFile(dir, file, content string) error {
-	if err := os.MkdirAll(dir, 0755); err != nil {
-		return err
-	}
-	return ioutil.WriteFile(path.Join(dir, file), []byte(content), 0644)
-}
-
-// localDB creates a local db with testVulns and index as contents.
-func localDB(t *testing.T) (string, error) {
-	dbName := t.TempDir()
-	for _, f := range []struct {
-		dir, filename, content string
-	}{
-		{"golang.org/example", "one.json", testVulns},
-		{"", "index.json", index},
-		{internal.IDDirectory, "ID.json", testVuln},
-		{internal.IDDirectory, "index.json", idIndex},
-	} {
-		if err := createDirAndFile(path.Join(dbName, f.dir), f.filename, f.content); err != nil {
-			return "", err
-		}
-	}
-	return dbName, nil
-}
-
-func newTestServer() *httptest.Server {
-	dataHandler := func(data string) http.HandlerFunc {
-		return func(w http.ResponseWriter, _ *http.Request) {
-			io.WriteString(w, data)
-		}
-	}
-
-	mux := http.NewServeMux()
-	mux.HandleFunc("/golang.org/example/one.json", dataHandler(testVulns))
-	mux.HandleFunc("/index.json", dataHandler(index))
-	mux.HandleFunc(fmt.Sprintf("/%s/ID.json", internal.IDDirectory), dataHandler(testVuln))
-	mux.HandleFunc("/ID/index.json", func(w http.ResponseWriter, r *http.Request) {
-		io.WriteString(w, idIndex)
-	})
-	return httptest.NewServer(mux)
-}
-
-func TestClient(t *testing.T) {
-	if runtime.GOOS == "js" {
-		t.Skip("skipping test: no network on js")
-	}
-
-	// Create a local http database.
-	srv := newTestServer()
-	defer srv.Close()
-	u, err := url.Parse(srv.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	dbName := u.Hostname()
-
-	// Create a local file database.
-	localDBName, err := localDB(t)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(localDBName)
-
-	for _, test := range []struct {
-		name   string
-		source string
-		cache  Cache
-		// cache summary for testVuln
-		summary string
-	}{
-		// Test the http client without any cache.
-		{name: "http-no-cache", source: srv.URL, cache: nil, summary: ""},
-		// Test the http client with empty cache.
-		{name: "http-empty-cache", source: srv.URL, cache: freshTestCache(), summary: ""},
-		// Test the client with non-stale cache containing a version of testVuln2 where Summary="cached".
-		{name: "http-cache", source: srv.URL, cache: cachedTestVuln(dbName), summary: "cached"},
-		// Repeat the same for local file client.
-		{name: "file-no-cache", source: "file://" + localDBName, cache: nil, summary: ""},
-		{name: "file-empty-cache", source: "file://" + localDBName, cache: freshTestCache(), summary: ""},
-		// Cache does not play a role in local file databases.
-		{name: "file-cache", source: "file://" + localDBName, cache: cachedTestVuln(localDBName), summary: ""},
-	} {
-		client, err := NewClient([]string{test.source}, Options{HTTPCache: test.cache})
-		if err != nil {
-			t.Fatal(err)
-		}
-
-		vulns, err := client.GetByModule("golang.org/example/one")
-		if err != nil {
-			t.Fatal(err)
-		}
-
-		if len(vulns) != 1 {
-			t.Errorf("%s: want 1 vuln for golang.org/example/one; got %v", test.name, len(vulns))
-		}
-
-		if v := vulns[0]; v.Details != test.summary {
-			t.Errorf("%s: want '%s' summary for testVuln; got '%s'", test.name, test.summary, v.Details)
-		}
-	}
-}
-
-func TestCorrectFetchesNoCache(t *testing.T) {
-	fetches := map[string]int{}
-	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		fetches[r.URL.Path]++
-		if r.URL.Path == "/index.json" {
-			j, _ := json.Marshal(osv.DBIndex{
-				"a": time.Now(),
-				"b": time.Now(),
-			})
-			w.Write(j)
-		} else {
-			w.Write([]byte("[]"))
-		}
-	}))
-	defer ts.Close()
-
-	hs := &httpSource{url: ts.URL, c: new(http.Client)}
-	for _, module := range []string{"a", "b", "c"} {
-		if _, err := hs.GetByModule(module); err != nil {
-			t.Fatalf("unexpected error: %s", err)
-		}
-	}
-	expectedFetches := map[string]int{"/index.json": 3, "/a.json": 1, "/b.json": 1}
-	if !reflect.DeepEqual(fetches, expectedFetches) {
-		t.Errorf("unexpected fetches, got %v, want %v", fetches, expectedFetches)
-	}
-}
-
-// Make sure that a cached index is used in the case it is stale
-// but there were no changes to it at the server side.
-func TestCorrectFetchesNoChangeIndex(t *testing.T) {
-	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		if r.URL.Path == "/index.json" {
-			w.WriteHeader(http.StatusNotModified)
-		}
-	}))
-	defer ts.Close()
-	url, _ := url.Parse(ts.URL)
-
-	// set timestamp so that cached index is stale,
-	// i.e., more than two hours old.
-	timeStamp := time.Now().Add(time.Hour * (-3))
-	index := osv.DBIndex{"a": timeStamp}
-	cache := freshTestCache()
-	cache.WriteIndex(url.Hostname(), index, timeStamp)
-
-	e := &osv.Entry{
-		ID:       "ID1",
-		Modified: timeStamp,
-	}
-	cache.WriteEntries(url.Hostname(), "a", []*osv.Entry{e})
-
-	client, err := NewClient([]string{ts.URL}, Options{HTTPCache: cache})
-	if err != nil {
-		t.Fatal(err)
-	}
-	vulns, err := client.GetByModule("a")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !reflect.DeepEqual(vulns, []*osv.Entry{e}) {
-		t.Errorf("want %v vuln; got %v", e, vulns)
-	}
-}
-
-func TestClientByID(t *testing.T) {
-	if runtime.GOOS == "js" {
-		t.Skip("skipping test: no network on js")
-	}
-
-	srv := newTestServer()
-	defer srv.Close()
-
-	// Create a local file database.
-	localDBName, err := localDB(t)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(localDBName)
-
-	var want osv.Entry
-	if err := json.Unmarshal([]byte(testVuln), &want); err != nil {
-		t.Fatal(err)
-	}
-	for _, test := range []struct {
-		name   string
-		source string
-	}{
-		{name: "http", source: srv.URL},
-		{name: "file", source: "file://" + localDBName},
-	} {
-		t.Run(test.name, func(t *testing.T) {
-			client, err := NewClient([]string{test.source}, Options{})
-			if err != nil {
-				t.Fatal(err)
-			}
-			got, err := client.GetByID("ID")
-			if err != nil {
-				t.Fatal(err)
-			}
-			if !cmp.Equal(got, &want) {
-				t.Errorf("got\n%+v\nwant\n%+v", got, &want)
-			}
-		})
-	}
-}
-
-func TestListIDs(t *testing.T) {
-	if runtime.GOOS == "js" {
-		t.Skip("skipping test: no network on js")
-	}
-
-	srv := newTestServer()
-	defer srv.Close()
-
-	// Create a local file database.
-	localDBName, err := localDB(t)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(localDBName)
-
-	want := []string{"ID"}
-	for _, test := range []struct {
-		name   string
-		source string
-	}{
-		{name: "http", source: srv.URL},
-		{name: "file", source: "file://" + localDBName},
-	} {
-		t.Run(test.name, func(t *testing.T) {
-			client, err := NewClient([]string{test.source}, Options{})
-			if err != nil {
-				t.Fatal(err)
-			}
-			got, err := client.ListIDs()
-			if err != nil {
-				t.Fatal(err)
-			}
-			if !cmp.Equal(got, want) {
-				t.Errorf("got\n%+v\nwant\n%+v", got, want)
-			}
-		})
-	}
-}
