Initial commit: Gitea MCP Server
This commit is contained in:
@@ -0,0 +1,398 @@
|
||||
package actions
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMatchPattern(t *testing.T) {
|
||||
tests := []struct {
|
||||
filename string
|
||||
pattern string
|
||||
want bool
|
||||
}{
|
||||
{"build.yml", "*", true},
|
||||
{"build.yml", "*.*", true},
|
||||
{"build.yml", "*.yml", true},
|
||||
{"build.yaml", "*.yml", true},
|
||||
{"build.yaml", "*.yaml", true},
|
||||
{"build-test.yml", "build-*.yml", true},
|
||||
{"build-test.yml", "*-test.yml", true},
|
||||
{"build.yml", "deploy*.yml", false},
|
||||
{"build.yml", "*.yaml", false},
|
||||
{"BUILD.YML", "*.yml", true},
|
||||
{"build.yml", "build.yml", true},
|
||||
{"deploy.yml", "build.yml", false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.filename+"_"+tt.pattern, func(t *testing.T) {
|
||||
got := matchPattern(tt.filename, tt.pattern)
|
||||
if got != tt.want {
|
||||
t.Fatalf("matchPattern(%q, %q) = %v, want %v", tt.filename, tt.pattern, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertYamlToInterface(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input interface{}
|
||||
expected interface{}
|
||||
}{
|
||||
{
|
||||
name: "string value",
|
||||
input: "hello",
|
||||
expected: "hello",
|
||||
},
|
||||
{
|
||||
name: "int value",
|
||||
input: 42,
|
||||
expected: 42,
|
||||
},
|
||||
{
|
||||
name: "simple map",
|
||||
input: map[string]interface{}{
|
||||
"name": "test",
|
||||
"val": 123,
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"name": "test",
|
||||
"val": 123,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nested map",
|
||||
input: map[string]interface{}{
|
||||
"level1": map[string]interface{}{
|
||||
"level2": "value",
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"level1": map[string]interface{}{
|
||||
"level2": "value",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "slice",
|
||||
input: []interface{}{"a", "b", "c"},
|
||||
expected: []interface{}{"a", "b", "c"},
|
||||
},
|
||||
{
|
||||
name: "map with interface keys",
|
||||
input: map[interface{}]interface{}{
|
||||
"key": "value",
|
||||
123: "numeric key",
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"key": "value",
|
||||
"123": "numeric key",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := convertYamlToInterface(tt.input)
|
||||
|
||||
if !deepEqual(got, tt.expected) {
|
||||
t.Fatalf("convertYamlToInterface() = %v, want %v", got, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func deepEqual(a, b interface{}) bool {
|
||||
switch av := a.(type) {
|
||||
case map[string]interface{}:
|
||||
bv, ok := b.(map[string]interface{})
|
||||
if !ok || len(av) != len(bv) {
|
||||
return false
|
||||
}
|
||||
for k, v := range av {
|
||||
if !deepEqual(v, bv[k]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case []interface{}:
|
||||
bv, ok := b.([]interface{})
|
||||
if !ok || len(av) != len(bv) {
|
||||
return false
|
||||
}
|
||||
for i, v := range av {
|
||||
if !deepEqual(v, bv[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
default:
|
||||
return a == b
|
||||
}
|
||||
}
|
||||
|
||||
func TestWorkflowFileStruct(t *testing.T) {
|
||||
wf := WorkflowFile{
|
||||
Name: "test.yml",
|
||||
Path: ".gitea/workflows/test.yml",
|
||||
SHA: "abc123",
|
||||
Size: 1024,
|
||||
Content: map[string]interface{}{"name": "Test Workflow"},
|
||||
RawContent: "name: Test Workflow",
|
||||
Encoding: "base64",
|
||||
}
|
||||
|
||||
if wf.Name != "test.yml" {
|
||||
t.Fatalf("Name = %q, want %q", wf.Name, "test.yml")
|
||||
}
|
||||
|
||||
if wf.Path != ".gitea/workflows/test.yml" {
|
||||
t.Fatalf("Path = %q, want %q", wf.Path, ".gitea/workflows/test.yml")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchPattern_EdgeCases(t *testing.T) {
|
||||
tests := []struct {
|
||||
filename string
|
||||
pattern string
|
||||
want bool
|
||||
}{
|
||||
// Edge cases for empty strings
|
||||
{"", "*", true},
|
||||
{"file.yml", "", false},
|
||||
{"", "", true},
|
||||
// Edge cases for special characters
|
||||
{"file-name.yml", "*-name.yml", true},
|
||||
{"file_name.yml", "*.yml", true},
|
||||
{"file.name.yml", "*.yml", true},
|
||||
// Edge case: only wildcard
|
||||
{"anything", "*", true},
|
||||
{"", "*", true},
|
||||
// Edge case: pattern equals filename
|
||||
{"exact.yml", "exact.yml", true},
|
||||
{"exact.yml", "exact.yaml", false},
|
||||
// Edge case: case sensitivity
|
||||
{"FILE.YML", "*.yml", true},
|
||||
{"File.Yml", "*.yml", true},
|
||||
// Edge case: middle wildcards
|
||||
{"build-test-deploy.yml", "*test*.yml", true},
|
||||
{"build-prod-deploy.yml", "*test*.yml", false},
|
||||
// Edge case: multiple extensions
|
||||
{"file.tar.gz", "*.gz", true},
|
||||
{"file.tar.gz", "*.tar.gz", true},
|
||||
// Edge case: dots in filename
|
||||
{".github/workflows/build.yml", "*.yml", true},
|
||||
// Edge case: numeric patterns
|
||||
{"build-123.yml", "build-*.yml", true},
|
||||
{"build-abc.yml", "build-*.yml", true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.filename+"_"+tt.pattern, func(t *testing.T) {
|
||||
got := matchPattern(tt.filename, tt.pattern)
|
||||
if got != tt.want {
|
||||
t.Fatalf("matchPattern(%q, %q) = %v, want %v", tt.filename, tt.pattern, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertYamlToInterface_EdgeCases(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input interface{}
|
||||
expected interface{}
|
||||
}{
|
||||
{
|
||||
name: "nil value",
|
||||
input: nil,
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "empty map",
|
||||
input: map[string]interface{}{},
|
||||
expected: map[string]interface{}{},
|
||||
},
|
||||
{
|
||||
name: "empty slice",
|
||||
input: []interface{}{},
|
||||
expected: []interface{}{},
|
||||
},
|
||||
{
|
||||
name: "nested empty structures",
|
||||
input: map[string]interface{}{
|
||||
"empty_map": map[string]interface{}{},
|
||||
"empty_slice": []interface{}{},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"empty_map": map[string]interface{}{},
|
||||
"empty_slice": []interface{}{},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "boolean value",
|
||||
input: true,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "float value",
|
||||
input: 3.14,
|
||||
expected: 3.14,
|
||||
},
|
||||
{
|
||||
name: "deeply nested map",
|
||||
input: map[string]interface{}{
|
||||
"level1": map[string]interface{}{
|
||||
"level2": map[string]interface{}{
|
||||
"level3": map[string]interface{}{
|
||||
"value": "deep",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"level1": map[string]interface{}{
|
||||
"level2": map[string]interface{}{
|
||||
"level3": map[string]interface{}{
|
||||
"value": "deep",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := convertYamlToInterface(tt.input)
|
||||
|
||||
if !deepEqual(got, tt.expected) {
|
||||
t.Fatalf("convertYamlToInterface() = %v, want %v", got, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWorkflowFileStruct_EdgeCases(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
file WorkflowFile
|
||||
want WorkflowFile
|
||||
}{
|
||||
{
|
||||
name: "empty file",
|
||||
file: WorkflowFile{},
|
||||
want: WorkflowFile{},
|
||||
},
|
||||
{
|
||||
name: "file with zero size",
|
||||
file: WorkflowFile{
|
||||
Name: "empty.yml",
|
||||
Path: ".gitea/workflows/empty.yml",
|
||||
SHA: "abc123",
|
||||
Size: 0,
|
||||
Content: nil,
|
||||
RawContent: "",
|
||||
Encoding: "",
|
||||
},
|
||||
want: WorkflowFile{
|
||||
Name: "empty.yml",
|
||||
Path: ".gitea/workflows/empty.yml",
|
||||
SHA: "abc123",
|
||||
Size: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "file with large size",
|
||||
file: WorkflowFile{
|
||||
Name: "large.yml",
|
||||
Path: ".gitea/workflows/large.yml",
|
||||
SHA: "def456",
|
||||
Size: 1024 * 1024 * 10, // 10MB
|
||||
Content: map[string]interface{}{"name": "Large Workflow"},
|
||||
RawContent: "name: Large Workflow\\n# ... lots of content ...",
|
||||
Encoding: "base64",
|
||||
},
|
||||
want: WorkflowFile{
|
||||
Name: "large.yml",
|
||||
Path: ".gitea/workflows/large.yml",
|
||||
SHA: "def456",
|
||||
Size: 1024 * 1024 * 10,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.file.Name != tt.want.Name {
|
||||
t.Errorf("Name = %q, want %q", tt.file.Name, tt.want.Name)
|
||||
}
|
||||
if tt.file.Path != tt.want.Path {
|
||||
t.Errorf("Path = %q, want %q", tt.file.Path, tt.want.Path)
|
||||
}
|
||||
if tt.file.SHA != tt.want.SHA {
|
||||
t.Errorf("SHA = %q, want %q", tt.file.SHA, tt.want.SHA)
|
||||
}
|
||||
if tt.file.Size != tt.want.Size {
|
||||
t.Errorf("Size = %d, want %d", tt.file.Size, tt.want.Size)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWorkflowFilesResultStruct_EdgeCases(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
result WorkflowFilesResult
|
||||
}{
|
||||
{
|
||||
name: "empty result",
|
||||
result: WorkflowFilesResult{
|
||||
Directory: "",
|
||||
Files: []WorkflowFile{},
|
||||
TotalCount: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nil files",
|
||||
result: WorkflowFilesResult{
|
||||
Directory: ".gitea/workflows",
|
||||
Files: nil,
|
||||
TotalCount: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "single file",
|
||||
result: WorkflowFilesResult{
|
||||
Directory: ".github/workflows",
|
||||
Files: []WorkflowFile{
|
||||
{Name: "ci.yml"},
|
||||
},
|
||||
TotalCount: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "many files",
|
||||
result: WorkflowFilesResult{
|
||||
Directory: ".gitea/workflows",
|
||||
Files: []WorkflowFile{
|
||||
{Name: "build.yml"},
|
||||
{Name: "test.yml"},
|
||||
{Name: "deploy.yml"},
|
||||
{Name: "lint.yml"},
|
||||
{Name: "security.yml"},
|
||||
},
|
||||
TotalCount: 5,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if len(tt.result.Files) != tt.result.TotalCount {
|
||||
t.Errorf("Files length (%d) != TotalCount (%d)", len(tt.result.Files), tt.result.TotalCount)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user