Blank identifier discarding results; verify intentional ignoring of return values
_, _ = scanForSheBang([]byte("#! /usr/bin/env perl -w"))
1// SPDX-License-Identifier: MIT23package processor45import (6 "slices"7 "strings"8 "testing"9)1011func TestDetectLanguage(t *testing.T) {12 ProcessConstants()13 AllowListExtensions = []string{"css"}14 _, ext := DetectLanguage("example.black.css")1516 if ext != "css" {17 t.Error("Expected css got", ext)18 }19 AllowListExtensions = []string{}20}2122func TestDetectLanguageMojoExtensions(t *testing.T) {23 ProcessConstants()2425 tests := map[string]string{26 "example.mojo": "mojo",27 "example.🔥": "🔥",28 }29 for filename, wantExtension := range tests {30 possible, extension := DetectLanguage(filename)31 if extension != wantExtension {32 t.Errorf("DetectLanguage(%q) extension = %q, want %q", filename, extension, wantExtension)33 }34 if !slices.Contains(possible, "Mojo") {35 t.Errorf("DetectLanguage(%q) languages = %v, want Mojo", filename, possible)36 }37 }38}3940func TestDetectSheBangEmpty(t *testing.T) {41 ProcessConstants()4243 x, y := DetectSheBang([]byte{})4445 if x != "" || y == nil {46 t.Error("Expected no match got", x)47 }4849 x, y = DetectSheBang(nil)5051 if x != "" || y == nil {52 t.Error("Expected no match got", x)53 }54}5556func TestDetectSheBangPerl(t *testing.T) {57 ProcessConstants()5859 cases := []string{60 "#!/usr/bin/perl",61 "#! /usr/bin/perl",62 "#!/usr/bin/perl -w",63 "#!/usr/bin/env perl",64 "#! /usr/bin/env perl",65 "#!/usr/bin/env perl -w",66 "#! /usr/bin/env perl -w",67 "#!/opt/local/bin/perl",68 "#!/usr/bin/perl5",69 }7071 for _, c := range cases {72 x, y := DetectSheBang([]byte(c))7374 if x != "Perl" || y != nil {75 t.Error("Expected Perl match got", x, "for", c)76 }77 }78}7980func TestDetectSheBangPhp(t *testing.T) {81 ProcessConstants()8283 cases := []string{84 "#!/usr/bin/php5",85 "#!/usr/bin/php",86 }8788 for _, c := range cases {89 x, y := DetectSheBang([]byte(c))9091 if x != "PHP" || y != nil {92 t.Error("Expected PHP match got", x)93 }94 }95}9697func TestDetectSheBangPython(t *testing.T) {98 ProcessConstants()99100 cases := []string{101 "#!/usr/bin/python",102 "#!/usr/bin/python2",103 "#!/usr/bin/python3",104 }105106 for _, c := range cases {107 x, y := DetectSheBang([]byte(c))108109 if x != "Python" || y != nil {110 t.Error("Expected Python match got", x)111 }112 }113}114115func TestDetectSheBangAWK(t *testing.T) {116 ProcessConstants()117118 cases := []string{119 "#!/usr/bin/awk",120 "#!/usr/bin/gawk",121 "#!/usr/bin/mawk",122 }123124 for _, c := range cases {125 x, y := DetectSheBang([]byte(c))126127 if x != "AWK" || y != nil {128 t.Error("Expected AWK match got", x)129 }130 }131}132133func TestDetectSheBangCsh(t *testing.T) {134 ProcessConstants()135136 cases := []string{137 "#!/bin/csh",138 "#!/bin/tcsh",139 }140141 for _, c := range cases {142 x, y := DetectSheBang([]byte(c))143144 if x != "C Shell" || y != nil {145 t.Error("Expected C Shell match got", x)146 }147 }148}149150func TestDetectSheBangD(t *testing.T) {151 ProcessConstants()152153 cases := []string{154 "#!/usr/bin/env rdmd",155 }156157 for _, c := range cases {158 x, y := DetectSheBang([]byte(c))159160 if x != "D" || y != nil {161 t.Error("Expected D match got", x)162 }163 }164}165166func TestDetectSheBangNode(t *testing.T) {167 ProcessConstants()168169 cases := []string{170 "#!/usr/bin/env node",171 "#!/usr/bin/node",172 }173174 for _, c := range cases {175 x, y := DetectSheBang([]byte(c))176177 if x != "JavaScript" || y != nil {178 t.Error("Expected JavaScript match got", x)179 }180 }181}182183func TestDetectSheBangLisp(t *testing.T) {184 ProcessConstants()185186 cases := []string{187 "#!/usr/bin/env sbcl",188 "#!/usr/bin/sbcl",189 }190191 for _, c := range cases {192 x, y := DetectSheBang([]byte(c))193194 if x != "Lisp" || y != nil {195 t.Error("Expected Lisp match got", x)196 }197 }198}199200func TestDetectSheBangRacket(t *testing.T) {201 ProcessConstants()202203 cases := []string{204 "#!/usr/bin/env racket",205 "#!/usr/bin/racket",206 }207208 for _, c := range cases {209 x, y := DetectSheBang([]byte(c))210211 if x != "Racket" || y != nil {212 t.Error("Expected Racket match got", x)213 }214 }215}216217func TestDetectSheBangFish(t *testing.T) {218 ProcessConstants()219220 cases := []string{221 "#!/usr/bin/env fish",222 "#!/usr/bin/fish",223 "#!/bin/fish",224 }225226 for _, c := range cases {227 x, y := DetectSheBang([]byte(c))228229 if x != "Fish" || y != nil {230 t.Error("Expected Fish match got", x)231 }232 }233}234235func TestDetectSheBangShell(t *testing.T) {236 ProcessConstants()237238 cases := []string{239 "#!/usr/bin/env sh",240 "#!/bin/sh",241 }242243 for _, c := range cases {244 x, y := DetectSheBang([]byte(c))245246 if x != "Shell" || y != nil {247 t.Error("Expected Shell match got", x)248 }249 }250}251252func TestDetectSheBangRuby(t *testing.T) {253 ProcessConstants()254255 cases := []string{256 "#!/usr/bin/env ruby",257 "#!/usr/bin/ruby",258 }259260 for _, c := range cases {261 x, y := DetectSheBang([]byte(c))262263 if x != "Ruby" || y != nil {264 t.Error("Expected Ruby match got", x)265 }266 }267}268269func TestDetectSheBangLua(t *testing.T) {270 ProcessConstants()271272 cases := []string{273 "#!/usr/bin/env lua",274 "#!/usr/bin/lua",275 }276277 for _, c := range cases {278 x, y := DetectSheBang([]byte(c))279280 if x != "Lua" || y != nil {281 t.Error("Expected Lua match got", x)282 }283 }284}285286func TestDetectSheBangMultiple(t *testing.T) {287 ProcessConstants()288289 x, y := DetectSheBang([]byte(`#!/python/perl/ruby`))290291 if x != "Ruby" || y != nil {292 t.Error("Expected Ruby match got", x)293 }294}295296func TestDetectSheBangMultipleNewLine(t *testing.T) {297 ProcessConstants()298299 data := `#!/python/perl/ruby300python perl fish`301 x, y := DetectSheBang([]byte(data))302303 if x != "Ruby" || y != nil {304 t.Error("Expected Ruby match got", x)305 }306}307308func TestScanSheBang(t *testing.T) {309 cases := []string{310 "#!/usr/bin/perl",311 "#! /usr/bin/perl",312 "#!/usr/bin/perl -w",313 "#!/usr/bin/env perl",314 "#! /usr/bin/env perl",315 "#!/usr/bin/env perl -w",316 "#! /usr/bin/env perl -w",317 "#!/opt/local/bin/perl",318 }319320 for _, c := range cases {321 r, _ := scanForSheBang([]byte(c))322323 if r != "perl" {324 t.Errorf("Expected 'perl' got '%s' for %s", r, c)325 }326 }327}328329// Randomly try things to see what happens330func TestScanSheBangFuzz(t *testing.T) {331 for range 1000 {332 x, _ := scanForSheBang([]byte(randStringBytes(100)))333334 if x == "NEVERHAPPEN" {335 t.Errorf("Errr wot?")336 }337 }338}339340func TestCheckFullNameSheBang(t *testing.T) {341 ProcessConstants()342343 r, n := DetectLanguage("name")344345 if n != "name" {346 t.Error("Expected name to return")347 }348349 if r[0] != "#!" {350 t.Error("Expected #! return")351 }352}353354func TestCheckFullNameLicense(t *testing.T) {355 ProcessConstants()356357 r, n := DetectLanguage("license")358359 if n != "license" {360 t.Error("Expected name to return")361 }362363 if r[0] != "License" {364 t.Error("Expected License return")365 }366}367368func TestCheckFullNameXMake(t *testing.T) {369 ProcessConstants()370371 r, n := DetectLanguage("xmake.lua")372373 if n != "xmake.lua" {374 t.Error("Expected xmake.lua to return")375 }376377 if r[0] != "XMake" {378 t.Error("Expected XMake return")379 }380381 // count xmake.lua as a lua file if AllowListExtensions was set382 AllowListExtensions = []string{"lua"}383 r, n = DetectLanguage("xmake.lua")384385 if n != "lua" {386 t.Error("Expected lua to return")387 }388389 if r[0] != "Lua" {390 t.Error("Expected Lua return")391 }392 AllowListExtensions = []string{}393}394395func TestGuessLanguageCoq(t *testing.T) {396 ProcessConstants()397398 res := DetermineLanguage("", "", []string{"Coq", "SystemVerilog"}, []byte(`Require Hypothesis Inductive`))399400 if res != "Coq" {401 t.Error("Expected guessed language to have been Coq got", res)402 }403}404405func TestGuessLanguageQtTranslationSource(t *testing.T) {406 ProcessConstants()407408 content := []byte(`<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="ca">`)409 res := DetermineLanguage("", "", []string{"Qt Translation Source", "TypeScript"}, content)410 if res != "Qt Translation Source" {411 t.Errorf("Expected guessed language to have been Qt Translation Source, got %s", res)412 }413}414415func TestGuessLanguageSystemVerilog(t *testing.T) {416 ProcessConstants()417418 res := DetermineLanguage("", "", []string{"Coq", "SystemVerilog"}, []byte(`endmodule posedge edge always wire`))419420 if res != "SystemVerilog" {421 t.Error("Expected guessed language to have been SystemVerilog got", res)422 }423}424425func TestDetectLanguageIEC61131S7DCL(t *testing.T) {426 ProcessConstants()427428 possible, ext := DetectLanguage("types.s7dcl")429 if ext != "s7dcl" {430 t.Error("Expected s7dcl got", ext)431 }432 found := slices.Contains(possible, "IEC61131-3")433 if !found {434 t.Error("Expected IEC61131-3 got", possible)435 }436}437438func TestGuessLanguageIEC61131SCL(t *testing.T) {439 ProcessConstants()440441 content := []byte(`FUNCTION_BLOCK "MotorControl"442VAR_INPUT443 Start : BOOL;444END_VAR445BEGIN446 IF Start THEN447 Speed := 100;448 END_IF;449END_FUNCTION_BLOCK`)450451 res := DetermineLanguage("motor.scl", "", []string{"IEC61131-3", "Scallop"}, content)452 if res != "IEC61131-3" {453 t.Error("Expected guessed language to have been IEC61131-3 got", res)454 }455}456457func TestGuessLanguageScallopSCL(t *testing.T) {458 ProcessConstants()459460 content := []byte(`rel classes = {0, 1, 2}461rel count_enroll_cs_in_class(c, n) :-462 n = count(s: student(c, s), enroll(s, "CS") where c: classes(c))463query count_enroll_cs_in_class`)464465 res := DetermineLanguage("scallop.scl", "", []string{"IEC61131-3", "Scallop"}, content)466 if res != "Scallop" {467 t.Error("Expected guessed language to have been Scallop got", res)468 }469}470471// .h is shared between C / C++ / Objective-C. These exercise the regex472// heuristic disambiguation added for https://github.com/boyter/scc/issues/574473474func TestDetectLanguageHeaderSharedExtension(t *testing.T) {475 ProcessConstants()476477 possible, ext := DetectLanguage("foo.h")478 if ext != "h" {479 t.Error("Expected h got", ext)480 }481 for _, want := range []string{"C Header", "C++ Header", "Objective C"} {482 if !slices.Contains(possible, want) {483 t.Errorf("Expected %s among candidates got %v", want, possible)484 }485 }486}487488func TestGuessLanguageHeaderCpp(t *testing.T) {489 ProcessConstants()490491 content := []byte(`#ifndef EXAMPLE_CLASS492#define EXAMPLE_CLASS493class ExampleClass {494 public:495 ExampleClass();496 private:497 int MethodB();498};499#endif`)500501 res := DetermineLanguage("example.h", "", []string{"C Header", "C++ Header", "Objective C"}, content)502 if res != "C++ Header" {503 t.Error("Expected guessed language to have been C++ Header got", res)504 }505}506507func TestGuessLanguageHeaderObjectiveC(t *testing.T) {508 ProcessConstants()509510 content := []byte(`#import <Foundation/Foundation.h>511512@interface MyClass : NSObject513@property (nonatomic, strong) NSArray *items;514@end`)515516 res := DetermineLanguage("myclass.h", "", []string{"C Header", "C++ Header", "Objective C"}, content)517 if res != "Objective C" {518 t.Error("Expected guessed language to have been Objective C got", res)519 }520}521522func TestGuessLanguageHeaderPlainCFallback(t *testing.T) {523 ProcessConstants()524525 content := []byte(`#ifndef FOO_H526#define FOO_H527int add(int a, int b);528void do_thing(void);529#endif`)530531 res := DetermineLanguage("foo.h", "", []string{"C Header", "C++ Header", "Objective C"}, content)532 if res != "C Header" {533 t.Error("Expected guessed language to have been C Header got", res)534 }535}536537// The result must not depend on the order candidates are supplied in, since538// ExtensionToLanguage is populated from a map with non-deterministic iteration.539func TestGuessLanguageHeaderDeterministic(t *testing.T) {540 ProcessConstants()541542 content := []byte(`template <typename T>543class Foo {544 std::vector<T> items;545};`)546547 orderings := [][]string{548 {"C Header", "C++ Header", "Objective C"},549 {"Objective C", "C++ Header", "C Header"},550 {"C++ Header", "Objective C", "C Header"},551 }552 for _, order := range orderings {553 res := DetermineLanguage("foo.h", "", order, content)554 if res != "C++ Header" {555 t.Errorf("Expected C++ Header for ordering %v got %s", order, res)556 }557 }558}559560func TestGuessLanguageLanguageSetNoPossible(t *testing.T) {561 res := DetermineLanguage("", "Java", []string{}, []byte(`endmodule posedge edge always wire`))562563 if res != "Java" {564 t.Error("Expected guessed language to have been Java got", res)565 }566}567568func TestGuessLanguageSingleLanguageSet(t *testing.T) {569 res := DetermineLanguage("", "Java", []string{"Rust"}, []byte(`endmodule posedge edge always wire`))570571 if res != "Rust" {572 t.Error("Expected guessed language to have been Rust got", res)573 }574}575576func TestGuessLanguageLanguageEmptyContent(t *testing.T) {577 res := DetermineLanguage("", "", []string{"Rust"}, []byte(``))578579 if res != "Rust" {580 t.Error("Expected guessed language to have been Rust got", res)581 }582}583584// Benchmarks below585586func BenchmarkScanSheBangFuzz(b *testing.B) {587 for i := 0; i < b.N; i++ {588 _, _ = scanForSheBang([]byte(randStringBytes(100)))589 }590}591592func BenchmarkScanSheBangReal(b *testing.B) {593 for i := 0; i < b.N; i++ {594 _, _ = scanForSheBang([]byte("#! /usr/bin/env perl -w"))595 }596}597598func BenchmarkDetermineLanguage(b *testing.B) {599 ProcessConstants()600601 coqContent := []byte("Require Hypothesis Inductive\n")602 systemVerilogContent := []byte("endmodule posedge edge always wire\n")603 largeCoqContent := []byte("Require Hypothesis Inductive\n" + strings.Repeat("x", 25_000))604 largeSystemVerilogContent := []byte("endmodule posedge edge always wire\n" + strings.Repeat("y", 25_000))605 possibleLanguages := []string{"Coq", "SystemVerilog"}606607 benchmarks := []struct {608 name string609 content []byte610 }{611 {name: "small_coq", content: coqContent},612 {name: "small_systemverilog", content: systemVerilogContent},613 {name: "large_coq_over_cutoff", content: largeCoqContent},614 {name: "large_systemverilog_over_cutoff", content: largeSystemVerilogContent},615 }616617 for _, benchmark := range benchmarks {618 b.Run(benchmark.name, func(b *testing.B) {619 b.ReportAllocs()620 b.SetBytes(int64(len(benchmark.content)))621622 for i := 0; i < b.N; i++ {623 _ = DetermineLanguage("", "", possibleLanguages, benchmark.content)624 }625 })626 }627}
Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.