mirror of
https://github.com/Dvorinka/Devour.git
synced 2026-06-04 04:23:02 +00:00
457 lines
12 KiB
Go
457 lines
12 KiB
Go
package quality
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestGetSupportedLanguages(t *testing.T) {
|
|
languages := GetSupportedLanguages()
|
|
|
|
if len(languages) == 0 {
|
|
t.Error("GetSupportedLanguages() should return at least one language")
|
|
}
|
|
|
|
expectedLanguages := []string{
|
|
"go", "typescript", "python", "java", "rust",
|
|
"javascript", "csharp", "dart",
|
|
}
|
|
|
|
if len(languages) != len(expectedLanguages) {
|
|
t.Errorf("GetSupportedLanguages() expected %d languages, got %d", len(expectedLanguages), len(languages))
|
|
}
|
|
|
|
// Check that all expected languages are present
|
|
languageMap := make(map[string]bool)
|
|
for _, lang := range languages {
|
|
languageMap[lang.Name] = true
|
|
}
|
|
|
|
for _, expected := range expectedLanguages {
|
|
if !languageMap[expected] {
|
|
t.Errorf("GetSupportedLanguages() missing expected language: %s", expected)
|
|
}
|
|
}
|
|
|
|
// Verify Go language configuration
|
|
var goConfig *LanguageConfig
|
|
for _, lang := range languages {
|
|
if lang.Name == "go" {
|
|
goConfig = &lang
|
|
break
|
|
}
|
|
}
|
|
|
|
if goConfig == nil {
|
|
t.Error("GetSupportedLanguages() should include Go language")
|
|
return
|
|
}
|
|
|
|
expectedGoExtensions := []string{".go"}
|
|
if len(goConfig.Extensions) != len(expectedGoExtensions) {
|
|
t.Errorf("Go expected %d extensions, got %d", len(expectedGoExtensions), len(goConfig.Extensions))
|
|
}
|
|
|
|
for i, ext := range goConfig.Extensions {
|
|
if ext != expectedGoExtensions[i] {
|
|
t.Errorf("Go extension %d expected %s, got %s", i, expectedGoExtensions[i], ext)
|
|
}
|
|
}
|
|
|
|
expectedGoMarkers := []string{"go.mod", "go.sum"}
|
|
if len(goConfig.MarkerFiles) != len(expectedGoMarkers) {
|
|
t.Errorf("Go expected %d marker files, got %d", len(expectedGoMarkers), len(goConfig.MarkerFiles))
|
|
}
|
|
|
|
if goConfig.DefaultSrc != "." {
|
|
t.Errorf("Go expected default src '.', got %s", goConfig.DefaultSrc)
|
|
}
|
|
}
|
|
|
|
func TestNewDefaultFileFinder(t *testing.T) {
|
|
finder := NewDefaultFileFinder()
|
|
|
|
if finder == nil {
|
|
t.Error("NewDefaultFileFinder() should not return nil")
|
|
}
|
|
|
|
// Test that it implements the interface
|
|
var _ FileFinder = finder
|
|
}
|
|
|
|
func TestDefaultFileFinder_FindFiles(t *testing.T) {
|
|
// Create temporary directory for testing
|
|
tmpDir, err := os.MkdirTemp("", "filefinder_test")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp dir: %v", err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
finder := NewDefaultFileFinder()
|
|
|
|
// Create test files
|
|
testFiles := map[string]string{
|
|
"main.go": "package main",
|
|
"utils.go": "package utils",
|
|
"test.ts": "export function test() {}",
|
|
"app.py": "print('hello')",
|
|
"Main.java": "public class Main {}",
|
|
"lib.rs": "fn main() {}",
|
|
"script.js": "console.log('hello')",
|
|
"Program.cs": "using System;",
|
|
"main.dart": "void main() {}",
|
|
"readme.md": "# README",
|
|
"config.json": "{}",
|
|
}
|
|
|
|
for file, content := range testFiles {
|
|
fullPath := filepath.Join(tmpDir, file)
|
|
err := os.WriteFile(fullPath, []byte(content), 0644)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create test file %s: %v", file, err)
|
|
}
|
|
}
|
|
|
|
// Create subdirectory with hidden folder
|
|
os.MkdirAll(filepath.Join(tmpDir, ".hidden"), 0755)
|
|
os.WriteFile(filepath.Join(tmpDir, ".hidden", "hidden.go"), []byte("package hidden"), 0644)
|
|
|
|
// Create node_modules directory (should be skipped)
|
|
os.MkdirAll(filepath.Join(tmpDir, "node_modules"), 0755)
|
|
os.WriteFile(filepath.Join(tmpDir, "node_modules", "index.js"), []byte("module code"), 0644)
|
|
|
|
tests := []struct {
|
|
name string
|
|
language string
|
|
expected int
|
|
}{
|
|
{"go files", "go", 2},
|
|
{"typescript files", "typescript", 1},
|
|
{"python files", "python", 1},
|
|
{"java files", "java", 1},
|
|
{"rust files", "rust", 1},
|
|
{"javascript files", "javascript", 1},
|
|
{"csharp files", "csharp", 1},
|
|
{"dart files", "dart", 1},
|
|
{"unknown language defaults to go", "unknown", 2},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
files, err := finder.FindFiles(tmpDir, tt.language)
|
|
if err != nil {
|
|
t.Errorf("FindFiles() failed: %v", err)
|
|
}
|
|
if len(files) != tt.expected {
|
|
t.Errorf("FindFiles() expected %d files, got %d", tt.expected, len(files))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDefaultFileFinder_FindFiles_EmptyDirectory(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "filefinder_empty_test")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp dir: %v", err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
finder := NewDefaultFileFinder()
|
|
files, err := finder.FindFiles(tmpDir, "go")
|
|
|
|
if err != nil {
|
|
t.Errorf("FindFiles() failed: %v", err)
|
|
}
|
|
|
|
if len(files) != 0 {
|
|
t.Errorf("FindFiles() expected 0 files, got %d", len(files))
|
|
}
|
|
}
|
|
|
|
func TestDefaultFileFinder_FindFiles_DotPathRootNotSkipped(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "filefinder_dot_root_test")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp dir: %v", err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
if err := os.WriteFile(filepath.Join(tmpDir, "main.go"), []byte("package main"), 0644); err != nil {
|
|
t.Fatalf("Failed to write go file: %v", err)
|
|
}
|
|
|
|
cwd, err := os.Getwd()
|
|
if err != nil {
|
|
t.Fatalf("Failed to get cwd: %v", err)
|
|
}
|
|
defer func() { _ = os.Chdir(cwd) }()
|
|
|
|
if err := os.Chdir(tmpDir); err != nil {
|
|
t.Fatalf("Failed to chdir: %v", err)
|
|
}
|
|
|
|
finder := NewDefaultFileFinder()
|
|
files, err := finder.FindFiles(".", "go")
|
|
if err != nil {
|
|
t.Fatalf("FindFiles() failed: %v", err)
|
|
}
|
|
if len(files) != 1 {
|
|
t.Fatalf("FindFiles('.') expected 1 file, got %d", len(files))
|
|
}
|
|
}
|
|
|
|
func TestDefaultFileFinder_FindFiles_NonExistentPath(t *testing.T) {
|
|
finder := NewDefaultFileFinder()
|
|
files, err := finder.FindFiles("/non/existent/path", "go")
|
|
|
|
if err == nil {
|
|
t.Error("FindFiles() should fail for non-existent path")
|
|
}
|
|
|
|
if len(files) != 0 {
|
|
t.Errorf("FindFiles() expected 0 files for error case, got %d", len(files))
|
|
}
|
|
}
|
|
|
|
func TestDefaultFileFinder_IsSourceFile(t *testing.T) {
|
|
finder := NewDefaultFileFinder()
|
|
|
|
tests := []struct {
|
|
name string
|
|
path string
|
|
language string
|
|
expected bool
|
|
}{
|
|
{"go file", "main.go", "go", true},
|
|
{"typescript file", "app.ts", "typescript", true},
|
|
{"tsx file", "component.tsx", "typescript", true},
|
|
{"python file", "script.py", "python", true},
|
|
{"java file", "Main.java", "java", true},
|
|
{"rust file", "lib.rs", "rust", true},
|
|
{"javascript file", "app.js", "javascript", true},
|
|
{"jsx file", "component.jsx", "javascript", true},
|
|
{"csharp file", "Program.cs", "csharp", true},
|
|
{"dart file", "main.dart", "dart", true},
|
|
{"markdown file", "readme.md", "go", false},
|
|
{"json file", "config.json", "go", false},
|
|
{"text file", "notes.txt", "go", false},
|
|
{"unknown language defaults to go", "script.rb", "ruby", false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := finder.IsSourceFile(tt.path, tt.language)
|
|
if result != tt.expected {
|
|
t.Errorf("IsSourceFile(%s, %s) = %v, want %v", tt.path, tt.language, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDetectLanguage(t *testing.T) {
|
|
// Create temporary directory for testing
|
|
tmpDir, err := os.MkdirTemp("", "detect_language_test")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp dir: %v", err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
tests := []struct {
|
|
name string
|
|
setup func() string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "go project with go.mod",
|
|
setup: func() string {
|
|
dir, _ := os.MkdirTemp("", "go_test")
|
|
os.WriteFile(filepath.Join(dir, "go.mod"), []byte("module test"), 0644)
|
|
return dir
|
|
},
|
|
expected: "go",
|
|
},
|
|
{
|
|
name: "typescript project with package.json",
|
|
setup: func() string {
|
|
dir, _ := os.MkdirTemp("", "ts_test")
|
|
os.WriteFile(filepath.Join(dir, "package.json"), []byte("{}"), 0644)
|
|
return dir
|
|
},
|
|
expected: "typescript",
|
|
},
|
|
{
|
|
name: "typescript project with tsconfig.json",
|
|
setup: func() string {
|
|
dir, _ := os.MkdirTemp("", "tsconfig_test")
|
|
os.WriteFile(filepath.Join(dir, "tsconfig.json"), []byte("{}"), 0644)
|
|
return dir
|
|
},
|
|
expected: "typescript",
|
|
},
|
|
{
|
|
name: "python project with requirements.txt",
|
|
setup: func() string {
|
|
dir, _ := os.MkdirTemp("", "py_test")
|
|
os.WriteFile(filepath.Join(dir, "requirements.txt"), []byte("flask"), 0644)
|
|
return dir
|
|
},
|
|
expected: "python",
|
|
},
|
|
{
|
|
name: "python project with setup.py",
|
|
setup: func() string {
|
|
dir, _ := os.MkdirTemp("", "setup_test")
|
|
os.WriteFile(filepath.Join(dir, "setup.py"), []byte("from setuptools import setup"), 0644)
|
|
return dir
|
|
},
|
|
expected: "python",
|
|
},
|
|
{
|
|
name: "python project with pyproject.toml",
|
|
setup: func() string {
|
|
dir, _ := os.MkdirTemp("", "pyproject_test")
|
|
os.WriteFile(filepath.Join(dir, "pyproject.toml"), []byte("[build-system]"), 0644)
|
|
return dir
|
|
},
|
|
expected: "python",
|
|
},
|
|
{
|
|
name: "java project with pom.xml",
|
|
setup: func() string {
|
|
dir, _ := os.MkdirTemp("", "java_test")
|
|
os.WriteFile(filepath.Join(dir, "pom.xml"), []byte("<project></project>"), 0644)
|
|
return dir
|
|
},
|
|
expected: "java",
|
|
},
|
|
{
|
|
name: "java project with build.gradle",
|
|
setup: func() string {
|
|
dir, _ := os.MkdirTemp("", "gradle_test")
|
|
os.WriteFile(filepath.Join(dir, "build.gradle"), []byte("plugins {}"), 0644)
|
|
return dir
|
|
},
|
|
expected: "java",
|
|
},
|
|
{
|
|
name: "rust project with Cargo.toml",
|
|
setup: func() string {
|
|
dir, _ := os.MkdirTemp("", "rust_test")
|
|
os.WriteFile(filepath.Join(dir, "Cargo.toml"), []byte("[package]"), 0644)
|
|
return dir
|
|
},
|
|
expected: "rust",
|
|
},
|
|
{
|
|
name: "javascript project with package.json",
|
|
setup: func() string {
|
|
dir, _ := os.MkdirTemp("", "js_test")
|
|
os.WriteFile(filepath.Join(dir, "package.json"), []byte("{}"), 0644)
|
|
return dir
|
|
},
|
|
expected: "typescript", // TypeScript comes before JavaScript in the list
|
|
},
|
|
{
|
|
name: "csharp project with .csproj file",
|
|
setup: func() string {
|
|
dir, _ := os.MkdirTemp("", "cs_test")
|
|
os.WriteFile(filepath.Join(dir, "Project.csproj"), []byte("<Project></Project>"), 0644)
|
|
return dir
|
|
},
|
|
expected: "csharp",
|
|
},
|
|
{
|
|
name: "csharp project with .sln file",
|
|
setup: func() string {
|
|
dir, _ := os.MkdirTemp("", "sln_test")
|
|
os.WriteFile(filepath.Join(dir, "Solution.sln"), []byte("Microsoft Visual Studio Solution File"), 0644)
|
|
return dir
|
|
},
|
|
expected: "csharp",
|
|
},
|
|
{
|
|
name: "dart project with pubspec.yaml",
|
|
setup: func() string {
|
|
dir, _ := os.MkdirTemp("", "dart_test")
|
|
os.WriteFile(filepath.Join(dir, "pubspec.yaml"), []byte("name: test"), 0644)
|
|
return dir
|
|
},
|
|
expected: "dart",
|
|
},
|
|
{
|
|
name: "no markers defaults to go",
|
|
setup: func() string {
|
|
dir, _ := os.MkdirTemp("", "empty_test")
|
|
return dir
|
|
},
|
|
expected: "go",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
dir := tt.setup()
|
|
defer os.RemoveAll(dir)
|
|
|
|
detected := DetectLanguage(dir)
|
|
if detected != tt.expected {
|
|
t.Errorf("DetectLanguage() = %v, want %v", detected, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDetectLanguage_NonExistentPath(t *testing.T) {
|
|
result := DetectLanguage("/non/existent/path")
|
|
if result != "go" {
|
|
t.Errorf("DetectLanguage() should default to 'go' for non-existent path, got %s", result)
|
|
}
|
|
}
|
|
|
|
func TestDetectLanguage_MultipleMarkers(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "multiple_markers_test")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp dir: %v", err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
// Create multiple marker files - should detect the first one in order
|
|
os.WriteFile(filepath.Join(tmpDir, "go.mod"), []byte("module test"), 0644)
|
|
os.WriteFile(filepath.Join(tmpDir, "package.json"), []byte("{}"), 0644)
|
|
|
|
detected := DetectLanguage(tmpDir)
|
|
if detected != "go" {
|
|
t.Errorf("DetectLanguage() should detect 'go' (first in order), got %s", detected)
|
|
}
|
|
}
|
|
|
|
func TestLanguageConfig_Structure(t *testing.T) {
|
|
languages := GetSupportedLanguages()
|
|
|
|
for _, lang := range languages {
|
|
if lang.Name == "" {
|
|
t.Error("LanguageConfig.Name should not be empty")
|
|
}
|
|
|
|
if len(lang.Extensions) == 0 {
|
|
t.Errorf("LanguageConfig %s should have at least one extension", lang.Name)
|
|
}
|
|
|
|
if len(lang.MarkerFiles) == 0 {
|
|
t.Errorf("LanguageConfig %s should have at least one marker file", lang.Name)
|
|
}
|
|
|
|
if lang.DefaultSrc == "" {
|
|
t.Errorf("LanguageConfig %s should have a default source directory", lang.Name)
|
|
}
|
|
|
|
// Verify extensions start with dot
|
|
for _, ext := range lang.Extensions {
|
|
if !strings.HasPrefix(ext, ".") {
|
|
t.Errorf("LanguageConfig %s extension %s should start with '.'", lang.Name, ext)
|
|
}
|
|
}
|
|
}
|
|
}
|