Blank identifier discarding results; verify intentional ignoring of return values
fi, _ = os.Stat("../examples/countaspattern/app.rb")
1// SPDX-License-Identifier: MIT23package processor45import (6 "math/rand/v2"7 "os"8 "path/filepath"9 "runtime"10 "testing"11)1213func TestGetExtension(t *testing.T) {14 got := getExtension("something.c")15 expected := "c"1617 if got != expected {18 t.Errorf("Expected %s got %s", expected, got)19 }20}2122func TestGetExtensionNoExtension(t *testing.T) {23 got := getExtension("something")24 expected := "something"2526 if got != expected {27 t.Errorf("Expected %s got %s", expected, got)28 }29}3031func TestGetExtensionMultipleDots(t *testing.T) {32 got := getExtension(".travis.yml")33 expected := "travis.yml"3435 if got != expected {36 t.Errorf("Expected %s got %s", expected, got)37 }38}3940func TestGetExtensionMultipleExtensions(t *testing.T) {41 got := getExtension("something.go.yml")42 expected := "go.yml"4344 if got != expected {45 t.Errorf("Expected %s got %s", expected, got)46 }47}4849func TestGetExtensionStartsWith(t *testing.T) {50 got := getExtension(".gitignore")51 expected := ".gitignore"5253 if got != expected {54 t.Errorf("Expected %s got %s", expected, got)55 }56}5758func TestGetExtensionTypeScriptDefinition(t *testing.T) {59 got := getExtension("test.d.ts")60 expected := "d.ts"6162 if got != expected {63 t.Errorf("Expected %s got %s", expected, got)64 }65}6667func TestGetExtensionSecondPass(t *testing.T) {68 got := getExtension("test.d.ts")69 got = getExtension(got)70 expected := "ts"7172 if got != expected {73 t.Errorf("Expected %s got %s", expected, got)74 }75}7677func TestNewFileJobCountAsPattern(t *testing.T) {78 defer func() {79 CountAsPattern = nil80 CountRules = nil81 compiledCountRules = nil82 delete(languageDatabase, "Ruby Spec")83 delete(languageDatabase, "Ruby App")84 delete(languageDatabase, "Rescued")85 }()8687 AllowListExtensions = []string{}88 // First matching rule wins, so the spec rule is ordered before a broad rule89 CountAsPattern = []string{90 "glob:*_spec.rb:Ruby Spec:Ruby",91 "glob:*.rb:Ruby App:Ruby",92 "glob:*.unknownext:Rescued:JavaScript",93 }94 CountRules = nil95 compiledCountRules = nil96 ProcessConstants()97 cleanVisitedPaths()9899 // A *_spec.rb path is relabelled to the new minted category100 fi, _ := os.Stat("../examples/countaspattern/foo_spec.rb")101 job := newFileJob("../examples/countaspattern/foo_spec.rb", "foo_spec.rb", fi)102 if job == nil || job.PossibleLanguages[0] != "Ruby Spec" {103 t.Fatalf("expected Ruby Spec, got %+v", job)104 }105106 // First-match-wins: app.rb matches *.rb only, so falls to the second rule107 cleanVisitedPaths()108 fi, _ = os.Stat("../examples/countaspattern/app.rb")109 job = newFileJob("../examples/countaspattern/app.rb", "app.rb", fi)110 if job == nil || job.PossibleLanguages[0] != "Ruby App" {111 t.Fatalf("expected Ruby App, got %+v", job)112 }113}114115func TestNewFileJobFullname(t *testing.T) {116 ProcessConstants()117 cleanVisitedPaths()118 AllowListExtensions = []string{}119120 fi, _ := os.Stat("../examples/issue114/makefile")121 job := newFileJob("../examples/issue114/", "makefile", fi)122123 if job.PossibleLanguages[0] != "Makefile" {124 t.Error("Expected makefile got", job.PossibleLanguages[0])125 }126}127128func TestNewFileJob(t *testing.T) {129 ProcessConstants()130 cleanVisitedPaths()131132 fi, _ := os.Stat("../examples/issue114/java")133 job := newFileJob("../examples/issue114/", "java", fi)134135 if job.PossibleLanguages[0] != "#!" {136 t.Error("Expected special value #! got", job.PossibleLanguages[0])137 }138}139140func TestNewFileJobGitIgnore(t *testing.T) {141 AllowListExtensions = []string{}142 ProcessConstants()143 cleanVisitedPaths()144 CountIgnore = true145146 fi, _ := os.Stat("../examples/issue114/.gitignore")147 job := newFileJob("../examples/issue114/", ".gitignore", fi)148149 if job.PossibleLanguages[0] != "gitignore" {150 t.Error("Expected gitignore got", job.PossibleLanguages[0])151 }152}153154func TestNewFileJobIgnore(t *testing.T) {155 AllowListExtensions = []string{}156 ProcessConstants()157 cleanVisitedPaths()158159 fi, _ := os.Stat("../examples/issue114/.ignore")160 job := newFileJob("../examples/issue114/", ".ignore", fi)161162 if job.PossibleLanguages[0] != "ignore" {163 t.Error("Expected ignore got", job.PossibleLanguages[0])164 }165}166167func TestNewFileJobLicense(t *testing.T) {168 ProcessConstants()169 cleanVisitedPaths()170171 fi, _ := os.Stat("../examples/issue114/license")172 job := newFileJob("../examples/issue114/", "license", fi)173174 if job.PossibleLanguages[0] != "License" {175 t.Error("Expected License got", job.PossibleLanguages[0])176 }177}178179func TestNewFileJobYAML(t *testing.T) {180 ProcessConstants()181 cleanVisitedPaths()182183 fi, _ := os.Stat("../examples/issue114/.travis.yml")184 job := newFileJob("../examples/issue114/", ".travis.yml", fi)185186 found := false187 for _, j := range job.PossibleLanguages {188 if j == "YAML" {189 found = true190 }191 }192193 if !found {194 t.Error("Expected YAML in but didn't find", job.PossibleLanguages)195 }196}197198func TestNewFileJobYAMLCloudformation(t *testing.T) {199 ProcessConstants()200 cleanVisitedPaths()201202 fi, _ := os.Stat("../examples/issue114/.travis.yml")203 job := newFileJob("../examples/issue114/", ".travis.yml", fi)204205 found := false206 for _, j := range job.PossibleLanguages {207 if j == "CloudFormation (YAML)" {208 found = true209 }210 }211212 if !found {213 t.Error("Expected CloudFormation in but didn't find", job.PossibleLanguages)214 }215}216217func TestNewFileJobSize(t *testing.T) {218 ProcessConstants()219 cleanVisitedPaths()220 NoLarge = true221 LargeByteCount = 1222223 fi, _ := os.Stat("file_test.go")224 job := newFileJob("file_test.go", "file_test.go", fi)225226 if job != nil {227 t.Error("Expected nil got", job)228 }229230 NoLarge = false231 LargeByteCount = 1000000232}233234func TestNewFileJobBrokenSymlink(t *testing.T) {235 if runtime.GOOS == "windows" {236 t.Skip("skipping symlink test on Windows due to privilege requirements")237 }238239 ProcessConstants()240 cleanVisitedPaths()241 IncludeSymLinks = true242 defer func() {243 IncludeSymLinks = false244 }()245246 // Create a temp directory to work in247 file := filepath.Join(t.TempDir(), "source.go")248 err := os.WriteFile(file, []byte("package main\n"), 0644)249 if err != nil {250 t.Fatal(err)251 }252 symPath := filepath.Join(t.TempDir(), "broken.go")253 err = os.Symlink(file, symPath)254 if err != nil {255 t.Fatal(err)256 }257 // Delete the file breaks the symlink258 err = os.Remove(file)259 if err != nil {260 t.Fatal(err)261 }262263 fi, _ := os.Lstat(symPath)264 job := newFileJob(symPath, "broken.go", fi)265266 if job != nil {267 t.Error("Expected nil for broken symlink got", job)268 }269}270271func TestNewFileJobUnsupportedSkippedByDefault(t *testing.T) {272 ProcessConstants()273 cleanVisitedPaths()274 AllowListExtensions = []string{}275 CountUnsupported = false276277 dir, _ := filepath.EvalSymlinks(t.TempDir())278 file := filepath.Join(dir, "data.unknownext")279 if err := os.WriteFile(file, []byte("one\ntwo\n"), 0644); err != nil {280 t.Fatal(err)281 }282283 fi, _ := os.Stat(file)284 job := newFileJob(file, "data.unknownext", fi)285286 if job != nil {287 t.Error("Expected nil for unsupported file without --count-unsupported, got", job)288 }289}290291func TestNewFileJobUnsupportedCounted(t *testing.T) {292 ProcessConstants()293 cleanVisitedPaths()294 AllowListExtensions = []string{}295 CountUnsupported = true296 defer func() { CountUnsupported = false }()297298 dir, _ := filepath.EvalSymlinks(t.TempDir())299 file := filepath.Join(dir, "data.unknownext")300 if err := os.WriteFile(file, []byte("one\ntwo\n"), 0644); err != nil {301 t.Fatal(err)302 }303304 fi, _ := os.Stat(file)305 job := newFileJob(file, "data.unknownext", fi)306307 if job == nil {308 t.Fatal("Expected a FileJob for unsupported file with --count-unsupported, got nil")309 }310 if len(job.PossibleLanguages) != 1 || job.PossibleLanguages[0] != UnknownLanguage {311 t.Errorf("Expected language %q got %v", UnknownLanguage, job.PossibleLanguages)312 }313314 // It should count as plain text: lines and code populated, no comments or315 // complexity since the Unknown category carries no language features.316 job.Content = []byte("one\ntwo\n")317 job.Language = DetermineLanguage(job.Filename, job.Language, job.PossibleLanguages, job.Content)318 if job.Language != UnknownLanguage {319 t.Errorf("Expected resolved language %q got %q", UnknownLanguage, job.Language)320 }321 CountStats(job)322 if job.Lines != 2 {323 t.Errorf("Expected 2 lines got %d", job.Lines)324 }325 if job.Code != 2 {326 t.Errorf("Expected 2 code lines got %d", job.Code)327 }328 if job.Comment != 0 || job.Complexity != 0 {329 t.Errorf("Expected no comments/complexity got comment=%d complexity=%d", job.Comment, job.Complexity)330 }331}332333func BenchmarkGetExtensionDifferent(b *testing.B) {334 for i := 0; i < b.N; i++ {335336 b.StopTimer()337 name := randStringBytes(3) + "." + randStringBytes(2)338 b.StartTimer()339340 getExtension(name)341 }342}343344func BenchmarkGetExtensionSame(b *testing.B) {345 name := randStringBytes(7) + "." + randStringBytes(3)346347 for i := 0; i < b.N; i++ {348 getExtension(name)349 }350}351352const letterBytes = "abcdefghijklmnopqrstuvwxyz"353354func randStringBytes(n int) string {355 b := make([]byte, n)356 for i := range b {357 b[i] = letterBytes[rand.IntN(len(letterBytes))]358 }359 return string(b)360}361362func TestNewFileJobCircularSymlink(t *testing.T) {363 if runtime.GOOS == "windows" {364 t.Skip("skipping symlink test on Windows due to privilege requirements")365 }366 ProcessConstants()367 cleanVisitedPaths()368 IncludeSymLinks = true369 defer func() { IncludeSymLinks = false }()370371 // Create a temp directory to work in372 dir, _ := filepath.EvalSymlinks(t.TempDir())373 link1 := filepath.Join(dir, "link1.go")374 link2 := filepath.Join(dir, "link2.go")375 // Create a loop: link1 -> link2 and link2 -> link1376 if err := os.Symlink(link2, link1); err != nil {377 t.Fatal("Failed to create first link:", err)378 }379 if err := os.Symlink(link1, link2); err != nil {380 t.Fatal("Failed to create circular link:", err)381 }382383 fi, err := os.Lstat(link1)384 if err != nil {385 t.Fatal(err)386 }387 // It should return the 'too many links' error.388 job := newFileJob(link1, "link1.go", fi)389390 if job != nil {391 t.Error("Expected nil for circular symlink, but got a FileJob")392 }393}394395func TestNewFileJobDuplicateCounting(t *testing.T) {396 if runtime.GOOS == "windows" {397 t.Skip("skipping symlink test on Windows due to privilege requirements")398 }399 ProcessConstants()400 cleanVisitedPaths()401 IncludeSymLinks = true402 defer func() { IncludeSymLinks = false }()403404 // on some systems like macOS, t.TempDir is also a symlink405 dir, _ := filepath.EvalSymlinks(t.TempDir())406 // Create a test file407 testFile := filepath.Join(dir, "file.go")408409 if err := os.WriteFile(testFile, []byte("package main"), 0644); err != nil {410 t.Fatal(err)411 }412413 // Create a symlink to the same file414 linkFile := filepath.Join(dir, "link.go")415 if err := os.Symlink(testFile, linkFile); err != nil {416 t.Fatalf("Failed to create link file: %s", err)417 }418 // Process the test file419 fi1, _ := os.Lstat(testFile)420 job1 := newFileJob(testFile, "file.go", fi1)421422 // Process the symlink (same target)423 fi2, _ := os.Lstat(linkFile)424 job2 := newFileJob(linkFile, "link.go", fi2)425426 // First count should go through427 if job1 == nil {428 t.Fatal("Expected first file job to be created")429 }430431 // Second count should be skipped432 if job2 != nil {433 t.Error("Expected nil for duplicate file through symlink, but got a FileJob")434 }435}
Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.