399 lines
8.6 KiB
Go
399 lines
8.6 KiB
Go
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)
|
|
}
|
|
})
|
|
}
|
|
}
|