a73x

internal/scanner/scanner_test.go

Ref:   Size: 3.9 KiB

package scanner

import (
	"os"
	"path/filepath"
	"strings"
	"testing"
)

func writeFile(t *testing.T, dir, name, content string) string {
	t.Helper()
	path := filepath.Join(dir, name)
	if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
		t.Fatal(err)
	}
	return path
}

func TestScanGoFileSingleUntaggedMarker(t *testing.T) {
	dir := t.TempDir()
	path := writeFile(t, dir, "foo.go", "package foo\n\n// @claude write a test for foo\nfunc Foo() {}\n")

	markers, err := Scan(path)
	if err != nil {
		t.Fatalf("Scan: %v", err)
	}
	if len(markers) != 1 {
		t.Fatalf("got %d markers, want 1: %#v", len(markers), markers)
	}
	m := markers[0]
	if m.Line != 3 {
		t.Errorf("Line = %d, want 3", m.Line)
	}
	if m.Text != "@claude write a test for foo" {
		t.Errorf("Text = %q, want %q", m.Text, "@claude write a test for foo")
	}
	if m.Tagged {
		t.Errorf("Tagged = true, want false")
	}
}

func TestScanPythonFile(t *testing.T) {
	dir := t.TempDir()
	path := writeFile(t, dir, "foo.py", "# @claude rename this\ndef foo(): pass\n")
	markers, err := Scan(path)
	if err != nil {
		t.Fatal(err)
	}
	if len(markers) != 1 || markers[0].Line != 1 || markers[0].Text != "@claude rename this" {
		t.Fatalf("got %#v", markers)
	}
}

func TestScanSQLFile(t *testing.T) {
	dir := t.TempDir()
	path := writeFile(t, dir, "q.sql", "-- @claude add an index\nSELECT 1;\n")
	markers, err := Scan(path)
	if err != nil {
		t.Fatal(err)
	}
	if len(markers) != 1 || markers[0].Text != "@claude add an index" {
		t.Fatalf("got %#v", markers)
	}
}

func TestScanCSSBlockComment(t *testing.T) {
	dir := t.TempDir()
	path := writeFile(t, dir, "s.css", "/* @claude make this responsive */\nbody {}\n")
	markers, err := Scan(path)
	if err != nil {
		t.Fatal(err)
	}
	if len(markers) != 1 || markers[0].Text != "@claude make this responsive" {
		t.Fatalf("got %#v", markers)
	}
}

func TestScanHTMLBlockComment(t *testing.T) {
	dir := t.TempDir()
	path := writeFile(t, dir, "x.html", "<!-- @claude add aria labels -->\n<div></div>\n")
	markers, err := Scan(path)
	if err != nil {
		t.Fatal(err)
	}
	if len(markers) != 1 || markers[0].Text != "@claude add aria labels" {
		t.Fatalf("got %#v", markers)
	}
}

func TestScanUnrecognizedExtensionSkipped(t *testing.T) {
	dir := t.TempDir()
	path := writeFile(t, dir, "weird.xyz", "// @claude do thing\n")
	markers, err := Scan(path)
	if err != nil {
		t.Fatal(err)
	}
	if len(markers) != 0 {
		t.Fatalf("expected skip, got %#v", markers)
	}
}

func TestScanMakefileByName(t *testing.T) {
	dir := t.TempDir()
	path := writeFile(t, dir, "Makefile", "# @claude add a lint target\nbuild:\n\techo hi\n")
	markers, err := Scan(path)
	if err != nil {
		t.Fatal(err)
	}
	if len(markers) != 1 || markers[0].Text != "@claude add a lint target" {
		t.Fatalf("got %#v", markers)
	}
}

func TestScanTaggedMarkerNotFiredButReported(t *testing.T) {
	dir := t.TempDir()
	path := writeFile(t, dir, "foo.go", "// @claude[fw-a1b2c3d4] write a test\n")
	markers, err := Scan(path)
	if err != nil {
		t.Fatal(err)
	}
	if len(markers) != 1 {
		t.Fatalf("want 1 marker, got %d", len(markers))
	}
	if !markers[0].Tagged || markers[0].UUID != "fw-a1b2c3d4" {
		t.Errorf("got %#v, want Tagged=true UUID=fw-a1b2c3d4", markers[0])
	}
}

func TestScanLargeFileSkipped(t *testing.T) {
	dir := t.TempDir()
	big := strings.Repeat("// filler line\n", 80_000) // > 1 MB
	path := writeFile(t, dir, "big.go", big+"// @claude do it\n")
	markers, err := Scan(path)
	if err != nil {
		t.Fatal(err)
	}
	if markers != nil {
		t.Fatalf("expected nil for oversized file, got %#v", markers)
	}
}

func TestScanBinaryFileSkipped(t *testing.T) {
	dir := t.TempDir()
	path := filepath.Join(dir, "blob.go")
	if err := os.WriteFile(path, []byte{0x00, 0x01, 0x02, '/', '/', ' ', '@', 'c', 'l', 'a', 'u', 'd', 'e', ' ', 'x'}, 0o644); err != nil {
		t.Fatal(err)
	}
	markers, err := Scan(path)
	if err != nil {
		t.Fatal(err)
	}
	if markers != nil {
		t.Fatalf("expected nil for binary file, got %#v", markers)
	}
}