1// SPDX-License-Identifier: MIT23package processor45import (6 "testing"78 "github.com/go-git/go-git/v5/plumbing"9)1011// TestBlobClassifyCacheMemoisesByHash verifies the cache returns the same12// result for repeated lookups of the same hash and only adds one entry.13// The classify method is the only call site for classifyHistoryBlob inside14// the cache, so len(cache.entries) is the underlying classifier call count.15func TestBlobClassifyCacheMemoisesByHash(t *testing.T) {16 ProcessConstants()17 cache := newBlobClassifyCache()18 blob := []byte("package a\nfunc A() {}\n")19 hash := plumbing.ComputeHash(plumbing.BlobObject, blob)2021 r1 := cache.classify(hash, "a.go", blob)22 r2 := cache.classify(hash, "a.go", blob)2324 if !r1.ok || !r2.ok {25 t.Fatalf("expected ok=true for both lookups, got %v / %v", r1.ok, r2.ok)26 }27 if r1.language != r2.language {28 t.Fatalf("language mismatch across hits: %q vs %q", r1.language, r2.language)29 }30 if got := len(cache.entries); got != 1 {31 t.Fatalf("expected 1 cache entry after two lookups of the same hash, got %d", got)32 }33}3435// TestBlobClassifyCacheKeysByHashNotPath confirms two different paths36// pointing at the same blob (a rename) classify once. The cache is37// hash-keyed by design — the rename inherits the original language.38func TestBlobClassifyCacheKeysByHashNotPath(t *testing.T) {39 ProcessConstants()40 cache := newBlobClassifyCache()41 content := []byte("package a\nfunc A() {}\n")42 hash := plumbing.ComputeHash(plumbing.BlobObject, content)4344 r1 := cache.classify(hash, "a.go", content)45 r2 := cache.classify(hash, "renamed.go", content)4647 if !r1.ok || !r2.ok {48 t.Fatalf("expected ok=true for both, got %v / %v", r1.ok, r2.ok)49 }50 if len(cache.entries) != 1 {51 t.Fatalf("expected 1 cache entry for same hash on different paths, got %d", len(cache.entries))52 }53 if r1.language != r2.language {54 t.Fatalf("expected same language for same hash; got %q vs %q", r1.language, r2.language)55 }56}5758// TestBlobClassifyCacheNegativeCaching confirms a blob the classifier59// rejects (unknown extension) is cached with ok=false. A repeat lookup of60// the same hash is a hit, so the classifier does not run a second time.61func TestBlobClassifyCacheNegativeCaching(t *testing.T) {62 ProcessConstants()63 cache := newBlobClassifyCache()64 blob := []byte("nothing identifiable here\n")65 hash := plumbing.ComputeHash(plumbing.BlobObject, blob)6667 r1 := cache.classify(hash, "weird.xx", blob)68 r2 := cache.classify(hash, "weird.xx", blob)6970 if r1.ok || r2.ok {71 t.Fatalf("expected ok=false for unknown-extension blob, got %v / %v", r1.ok, r2.ok)72 }73 if len(cache.entries) != 1 {74 t.Fatalf("expected negative result to be cached as 1 entry, got %d", len(cache.entries))75 }76}7778// TestBlobClassifyCacheSeparatesByHash sanity-checks that distinct hashes79// produce distinct cache entries.80func TestBlobClassifyCacheSeparatesByHash(t *testing.T) {81 ProcessConstants()82 cache := newBlobClassifyCache()83 a := []byte("package a\nfunc A() {}\n")84 b := []byte("package a\nfunc A() {}\nfunc B() {}\n")85 ha := plumbing.ComputeHash(plumbing.BlobObject, a)86 hb := plumbing.ComputeHash(plumbing.BlobObject, b)8788 cache.classify(ha, "a.go", a)89 cache.classify(hb, "a.go", b)90 cache.classify(ha, "a.go", a)9192 if len(cache.entries) != 2 {93 t.Fatalf("expected 2 cache entries for 2 distinct hashes, got %d", len(cache.entries))94 }95}9697// TestRunHistoryStillProducesHeadAndChanges is a smoke test that confirms98// threading the cache through runHistory / buildBaselineForObserver /99// commitChanges / buildHeadSnapshot doesn't change observable behavior: HEAD100// and per-commit changes still classify correctly.101func TestRunHistoryStillProducesHeadAndChanges(t *testing.T) {102 saveDepth := HistoryDepth103 HistoryDepth = 10104 t.Cleanup(func() { HistoryDepth = saveDepth })105106 dir := makeFixtureRepo(t, []map[string]string{107 {"a.go": "package a\nfunc A() {}\n"},108 {"b.go": "package b\nfunc B() {}\n"},109 {"c.go": "package c\nfunc C() {}\n"},110 })111112 cap := &captureObserver{}113 if _, err := runHistory(dir, cap); err != nil {114 t.Fatalf("runHistory: %v", err)115 }116 for _, name := range []string{"a.go", "b.go", "c.go"} {117 hf, ok := cap.snapshot.Files[name]118 if !ok {119 t.Fatalf("HEAD snapshot missing %s; got %v", name, cap.snapshot.Files)120 }121 if hf.Language != "Go" {122 t.Errorf("%s language = %q, want Go", name, hf.Language)123 }124 }125}
Findings
✓ No findings reported for this file.