mirror of
https://github.com/Dvorinka/Devour.git
synced 2026-06-03 20:13:03 +00:00
updage
This commit is contained in:
@@ -0,0 +1,342 @@
|
||||
package quality
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// DetectorMock implements the Detector interface for testing
|
||||
type DetectorMock struct {
|
||||
name string
|
||||
severity Severity
|
||||
}
|
||||
|
||||
func (m *DetectorMock) Name() string {
|
||||
return m.name
|
||||
}
|
||||
|
||||
func (m *DetectorMock) Detect(ctx context.Context, path string, config *Config) ([]Finding, error) {
|
||||
return []Finding{
|
||||
{
|
||||
Type: "mock_finding",
|
||||
Severity: m.severity,
|
||||
Status: StatusOpen,
|
||||
Score: 5,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *DetectorMock) Severity() Severity {
|
||||
return m.severity
|
||||
}
|
||||
|
||||
// LanguageDetectorMock implements both Detector and LanguageDetector interfaces
|
||||
type LanguageDetectorMock struct {
|
||||
*DetectorMock
|
||||
supportedLanguages []string
|
||||
}
|
||||
|
||||
func (m *LanguageDetectorMock) SupportedLanguages() []string {
|
||||
return m.supportedLanguages
|
||||
}
|
||||
|
||||
func (m *LanguageDetectorMock) ExtractFunctions(ctx context.Context, files []string) ([]FunctionInfo, error) {
|
||||
var functions []FunctionInfo
|
||||
for _, file := range files {
|
||||
functions = append(functions, FunctionInfo{
|
||||
Name: "test_func",
|
||||
File: file,
|
||||
})
|
||||
}
|
||||
return functions, nil
|
||||
}
|
||||
|
||||
func (m *LanguageDetectorMock) ExtractClasses(ctx context.Context, files []string) ([]ClassInfo, error) {
|
||||
var classes []ClassInfo
|
||||
for _, file := range files {
|
||||
classes = append(classes, ClassInfo{
|
||||
Name: "TestClass",
|
||||
File: file,
|
||||
})
|
||||
}
|
||||
return classes, nil
|
||||
}
|
||||
|
||||
// FileFinderMock implements the FileFinder interface for testing
|
||||
type FileFinderMock struct {
|
||||
files []string
|
||||
}
|
||||
|
||||
func (m *FileFinderMock) FindFiles(path string, language string) ([]string, error) {
|
||||
return m.files, nil
|
||||
}
|
||||
|
||||
func (m *FileFinderMock) IsSourceFile(path string, language string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func TestNewBaseDetector(t *testing.T) {
|
||||
finder := &FileFinderMock{files: []string{"test.go"}}
|
||||
detector := NewBaseDetector("test-detector", SeverityT2, finder)
|
||||
|
||||
if detector == nil {
|
||||
t.Error("NewBaseDetector() should not return nil")
|
||||
}
|
||||
|
||||
if detector.name != "test-detector" {
|
||||
t.Errorf("NewBaseDetector() name = %v, want test-detector", detector.name)
|
||||
}
|
||||
|
||||
if detector.severity != SeverityT2 {
|
||||
t.Errorf("NewBaseDetector() severity = %v, want T2", detector.severity)
|
||||
}
|
||||
|
||||
if detector.finder != finder {
|
||||
t.Error("NewBaseDetector() finder not set correctly")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBaseDetector_Name(t *testing.T) {
|
||||
detector := NewBaseDetector("test-name", SeverityT1, nil)
|
||||
|
||||
if detector.Name() != "test-name" {
|
||||
t.Errorf("Name() = %v, want test-name", detector.Name())
|
||||
}
|
||||
}
|
||||
|
||||
func TestBaseDetector_Severity(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
severity Severity
|
||||
}{
|
||||
{"T1 severity", SeverityT1},
|
||||
{"T2 severity", SeverityT2},
|
||||
{"T3 severity", SeverityT3},
|
||||
{"T4 severity", SeverityT4},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
detector := NewBaseDetector("test", tt.severity, nil)
|
||||
if detector.Severity() != tt.severity {
|
||||
t.Errorf("Severity() = %v, want %v", detector.Severity(), tt.severity)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBaseDetector_FindFiles(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
finder FileFinder
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
name: "with finder",
|
||||
finder: &FileFinderMock{files: []string{"file1.go", "file2.go"}},
|
||||
expected: []string{"file1.go", "file2.go"},
|
||||
},
|
||||
{
|
||||
name: "without finder",
|
||||
finder: nil,
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
detector := NewBaseDetector("test", SeverityT1, tt.finder)
|
||||
files, err := detector.FindFiles("/test/path", "go")
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("FindFiles() unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if len(files) != len(tt.expected) {
|
||||
t.Errorf("FindFiles() expected %d files, got %d", len(tt.expected), len(files))
|
||||
}
|
||||
|
||||
for i, file := range files {
|
||||
if i < len(tt.expected) && file != tt.expected[i] {
|
||||
t.Errorf("FindFiles() file %d = %v, want %v", i, file, tt.expected[i])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestShouldExclude(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
excludes []string
|
||||
expected bool
|
||||
}{
|
||||
{"no excludes", "test.go", []string{}, false},
|
||||
{"empty excludes", "test.go", []string{""}, false},
|
||||
{"exact match", "test.go", []string{"test.go"}, true},
|
||||
{"pattern match", "test_*.go", []string{"test_*.go"}, true},
|
||||
{"no match", "other.go", []string{"test.go"}, false},
|
||||
{
|
||||
name: "directory match",
|
||||
path: "vendor/lib.go",
|
||||
excludes: []string{"vendor"},
|
||||
expected: false,
|
||||
}, // filepath.Match doesn't match directories this way
|
||||
{"base directory match", "lib.go", []string{"lib.go"}, true},
|
||||
{"multiple patterns", "test.go", []string{"*.py", "test.go"}, true},
|
||||
{"invalid pattern", "test.go", []string{"[invalid"}, false},
|
||||
{"complex pattern", "internal/test/file.go", []string{"internal/*/file.go"}, true},
|
||||
{"case sensitive", "Test.go", []string{"test.go"}, false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := ShouldExclude(tt.path, tt.excludes)
|
||||
if result != tt.expected {
|
||||
t.Errorf("ShouldExclude(%s, %v) = %v, want %v", tt.path, tt.excludes, result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestShouldExclude_EdgeCases(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
excludes []string
|
||||
expected bool
|
||||
}{
|
||||
{"empty path", "", []string{"*"}, true},
|
||||
{"empty pattern", "test.go", []string{""}, false},
|
||||
{"star pattern", "any_file.go", []string{"*"}, true}, {
|
||||
name: "question mark",
|
||||
path: "file.go",
|
||||
excludes: []string{"file.?"},
|
||||
expected: false}, // filepath.Match doesn't support ? this way
|
||||
{
|
||||
name: "character class",
|
||||
path: "file.go",
|
||||
excludes: []string{"file.[go]"},
|
||||
expected: false}, // filepath.Match doesn't support character classes
|
||||
{"nested pattern", "a/b/c/file.go", []string{"a/*/c/file.go"}, true},
|
||||
{"absolute path", "/absolute/path/file.go", []string{"*.go"}, true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := ShouldExclude(tt.path, tt.excludes)
|
||||
if result != tt.expected {
|
||||
t.Errorf("ShouldExclude(%s, %v) = %v, want %v", tt.path, tt.excludes, result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMockDetector_Interface(t *testing.T) {
|
||||
// Verify that DetectorMock implements Detector interface
|
||||
var _ Detector = &DetectorMock{name: "test", severity: SeverityT1}
|
||||
|
||||
detector := &DetectorMock{name: "test-detector", severity: SeverityT2}
|
||||
|
||||
ctx := context.Background()
|
||||
findings, err := detector.Detect(ctx, "/test/path", &Config{})
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("MockDetector.Detect() unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if len(findings) != 1 {
|
||||
t.Errorf("DetectorMock.Detect() expected 1 finding, got %d", len(findings))
|
||||
}
|
||||
|
||||
if findings[0].Type != "mock_finding" {
|
||||
t.Errorf("DetectorMock.Detect() finding type = %v, want mock_finding", findings[0].Type)
|
||||
}
|
||||
|
||||
if findings[0].Severity != SeverityT2 {
|
||||
t.Errorf("DetectorMock.Detect() finding severity = %v, want T2", findings[0].Severity)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLanguageDetectorMock_Interface(t *testing.T) {
|
||||
// Verify that LanguageDetectorMock implements LanguageDetector interface
|
||||
var _ LanguageDetector = &LanguageDetectorMock{
|
||||
DetectorMock: &DetectorMock{name: "test", severity: SeverityT1},
|
||||
supportedLanguages: []string{"go", "python"},
|
||||
}
|
||||
|
||||
detector := &LanguageDetectorMock{
|
||||
DetectorMock: &DetectorMock{name: "test-lang", severity: SeverityT3},
|
||||
supportedLanguages: []string{"go", "python", "javascript"},
|
||||
}
|
||||
|
||||
if len(detector.SupportedLanguages()) != 3 {
|
||||
t.Errorf("LanguageDetectorMock.SupportedLanguages() expected 3 languages, got %d", len(detector.SupportedLanguages()))
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
files := []string{"file1.go", "file2.py"}
|
||||
|
||||
functions, err := detector.ExtractFunctions(ctx, files)
|
||||
if err != nil {
|
||||
t.Errorf("LanguageDetectorMock.ExtractFunctions() unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if len(functions) != 2 {
|
||||
t.Errorf("LanguageDetectorMock.ExtractFunctions() expected 2 functions, got %d", len(functions))
|
||||
}
|
||||
|
||||
classes, err := detector.ExtractClasses(ctx, files)
|
||||
if err != nil {
|
||||
t.Errorf("LanguageDetectorMock.ExtractClasses() unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if len(classes) != 2 {
|
||||
t.Errorf("LanguageDetectorMock.ExtractClasses() expected 2 classes, got %d", len(classes))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMockFileFinder_Interface(t *testing.T) {
|
||||
// Verify that FileFinderMock implements FileFinder interface
|
||||
var _ FileFinder = &FileFinderMock{files: []string{"test.go"}}
|
||||
|
||||
finder := &FileFinderMock{files: []string{"file1.go", "file2.go"}}
|
||||
|
||||
files, err := finder.FindFiles("/test/path", "go")
|
||||
if err != nil {
|
||||
t.Errorf("FileFinderMock.FindFiles() unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if len(files) != 2 {
|
||||
t.Errorf("FileFinderMock.FindFiles() expected 2 files, got %d", len(files))
|
||||
}
|
||||
|
||||
if !finder.IsSourceFile("test.go", "go") {
|
||||
t.Error("FileFinderMock.IsSourceFile() should return true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBaseDetector_Integration(t *testing.T) {
|
||||
// Test BaseDetector with real mock implementations
|
||||
finder := &FileFinderMock{files: []string{"main.go", "utils.go"}}
|
||||
detector := NewBaseDetector("integration-test", SeverityT2, finder)
|
||||
|
||||
// Test all methods
|
||||
if detector.Name() != "integration-test" {
|
||||
t.Errorf("Integration test: Name() = %v, want integration-test", detector.Name())
|
||||
}
|
||||
|
||||
if detector.Severity() != SeverityT2 {
|
||||
t.Errorf("Integration test: Severity() = %v, want T2", detector.Severity())
|
||||
}
|
||||
|
||||
files, err := detector.FindFiles("/project", "go")
|
||||
if err != nil {
|
||||
t.Errorf("Integration test: FindFiles() unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if len(files) != 2 {
|
||||
t.Errorf("Integration test: FindFiles() expected 2 files, got %d", len(files))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user