sourcegraph/lib/codeintel/languages/languages_test.go
Varun Gandhi 3437f8253d
chore: Centralize languages package as source-of-truth (#63292)
This patch does a few things:

- Adds `go-enry` packages to depguard, so that people do not
  accidentally use enry APIs instead of the corresponding APIs
  in the `languages` package.
- Adds more tests for different functions in the languages package
  to ensure mutual consistency in how language<->extension mappings
  are handled.
- Adds tests for enry upgrades
- Adds comments with IDs so that related parts in the code can be
   pieced together easily
2024-06-18 13:10:24 +00:00

95 lines
3.2 KiB
Go

package languages
import (
"testing"
"github.com/go-enry/go-enry/v2" //nolint:depguard - This package is allowed to use enry
"github.com/stretchr/testify/require"
"pgregory.net/rapid"
)
func TestGetLanguages(t *testing.T) {
const matlabContent = "function [out] = square(x)\nout = x * x;\nend"
const mathematicaContent = "f[x_] := x ^ 2\ng[y_] := f[y]"
const cppContent = "namespace x { }"
const cContent = "typedef struct { int x; } Int;"
const emptyContent = ""
testCases := []struct {
path string
content string
expectedLanguages []string
compareFirstOnly bool
}{
{path: "perlscript", content: "#!/usr/bin/env perl\n$version = $ARGV[0];", expectedLanguages: []string{"Perl"}},
{path: "rakuscript", content: "#!/usr/bin/env perl6\n$version = $ARGV[0];", expectedLanguages: []string{"Raku"}},
{path: "ambiguous.h", content: emptyContent, expectedLanguages: []string{"C", "C++", "Objective-C"}},
{path: "cpp.h", content: cppContent, expectedLanguages: []string{"C++"}},
{path: "c.h", content: cContent, expectedLanguages: []string{"C"}},
{path: "matlab.m", content: matlabContent, expectedLanguages: []string{"MATLAB"}, compareFirstOnly: true},
{path: "mathematica.m", content: mathematicaContent, expectedLanguages: []string{"Mathematica"}, compareFirstOnly: true},
{
path: "mathematica2.m",
content: `
s := StringRiffle[{"a", "b", "c", "d", "e"}, ", "]
Flatten[{{a, b}, {c, {d}, e}, {f, {g, h}}}]
square[x_] := x ^ 2
fourthpower[x_] := square[square[x]]
`,
expectedLanguages: []string{"Mathematica"},
compareFirstOnly: true,
},
}
for _, testCase := range testCases {
var getContent func() ([]byte, error)
if testCase.content != "" {
getContent = func() ([]byte, error) { return []byte(testCase.content), nil }
}
gotLanguages, err := GetLanguages(testCase.path, getContent)
require.NoError(t, err)
if testCase.compareFirstOnly {
require.Equal(t, testCase.expectedLanguages, gotLanguages[0:1])
continue
}
require.Equal(t, testCase.expectedLanguages, gotLanguages)
}
rapid.Check(t, func(t *rapid.T) {
path := rapid.String().Draw(t, "path")
content := rapid.SliceOfN(rapid.Byte(), 0, 100).Draw(t, "contents")
require.NotPanics(t, func() {
langs, err := GetLanguages(path, func() ([]byte, error) { return content, nil })
require.NoError(t, err)
if len(langs) != 0 {
for _, l := range langs {
require.NotEqual(t, enry.OtherLanguage, l)
}
}
})
})
rapid.Check(t, func(t *rapid.T) {
baseName := "abcd"
exts := []string{".h", ".m", ".unknown", ""}
extGens := []*rapid.Generator[string]{}
for _, ext := range exts {
extGens = append(extGens, rapid.Just(ext))
}
extension := rapid.OneOf(extGens...).Draw(t, "extension")
path := baseName + extension
contentGens := []*rapid.Generator[string]{}
for _, content := range []string{cContent, cppContent, mathematicaContent, matlabContent, emptyContent} {
contentGens = append(contentGens, rapid.Just(content))
}
content := rapid.OneOf(contentGens...).Draw(t, "content")
langs, err := GetLanguages(path, func() ([]byte, error) {
return []byte(content), nil
})
require.NoError(t, err)
for _, lang := range langs {
require.NotEqual(t, enry.OtherLanguage, lang)
}
})
}