Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .github/workflows/test-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,29 @@ jobs:
go-version-file: code/go.mod
cache-dependency-path: code/go.sum

- name: Detect Changed Files
id: changes
run: |
cd code
CHANGES=$(git diff --name-only origin/${{ github.base_ref }} HEAD -- data/)

if [ -z "$CHANGES" ]; then
echo "No changes in data directory."
echo "has_changes=false" >> $GITHUB_OUTPUT
else
echo "Found changes in data directory."
echo "has_changes=true" >> $GITHUB_OUTPUT
FILES_CSV=$(echo "$CHANGES" | tr '\n' ',')
echo "files=$FILES_CSV" >> $GITHUB_ENV
fi

- name: Run Syntax Tests (Affected Files Only)
if: steps.changes.outputs.has_changes == 'true'
run: |
cd code || exit 1
export CHANGED_FILES="${{ env.files }}"
go test -v .

- name: Set variables
run: |
echo "RELEASE_NAME=$(date +%Y%m%d%H%M%S)" >> $GITHUB_ENV
Expand Down
118 changes: 118 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package main

import (
"os"
"path/filepath"
"regexp"
"strings"
"testing"
)

var validDomainRegexp = regexp.MustCompile(`^[a-z0-9_\-\.]+$`)

func validateFile(t *testing.T, path string) {
list, err := Load(path)
if err != nil {
t.Errorf("❌ [Parse Error] File: %s | Error: %v", path, err)
return
}

for _, entry := range list.Entry {
switch entry.Type {
case "regexp":
if _, err := regexp.Compile(entry.Value); err != nil {
t.Errorf("❌ [Invalid Regex] File: %s | Rule: '%s' | Error: %v",
path, entry.Value, err)
}
case "domain", "full":
if strings.Contains(entry.Value, "http://") || strings.Contains(entry.Value, "https://") {
t.Errorf("❌ [Protocol Error] File: %s | Rule: '%s' | Remove http/s prefix",
path, entry.Value)
}
if strings.Contains(entry.Value, " ") {
t.Errorf("❌ [Spaces Error] File: %s | Rule: '%s' | Domain contains spaces",
path, entry.Value)
}
if !validDomainRegexp.MatchString(entry.Value) {
t.Errorf("❌ [Invalid Char] File: %s | Rule: '%s' | Contains illegal characters",
path, entry.Value)
}
case "include":
targetPath := filepath.Join("data", entry.Value)
if _, err := os.Stat(targetPath); os.IsNotExist(err) {
t.Errorf("❌ [Missing Include] File: %s | Target: '%s' does not exist",
path, entry.Value)
}
}
}
}

func TestDataSyntax(t *testing.T) {
changedFilesEnv := os.Getenv("CHANGED_FILES")

if changedFilesEnv != "" {
rawFiles := strings.Split(changedFilesEnv, ",")
var targetFiles []string

for _, f := range rawFiles {
f = strings.TrimSpace(f)
if f == "" {
continue
}
if strings.HasPrefix(f, "data/") || strings.HasPrefix(f, "data\\") {
if _, err := os.Stat(f); err == nil {
targetFiles = append(targetFiles, f)
}
}
}

total := len(targetFiles)
if total == 0 {
t.Log("ℹ️ CHANGED_FILES was set, but no valid 'data/' files were found to test.")
return
}

t.Logf("📝 Validating %d specific file(s):", total)
displayLimit := 5
for i, f := range targetFiles {
if i >= displayLimit {
t.Logf(" ... and %d more files.", total-i)
break
}
t.Logf(" - %s", f)
}
t.Log("---------------------------------------------------")

for _, f := range targetFiles {
validateFile(t, f)
}

} else {
dataDir := "data"
if _, err := os.Stat(dataDir); os.IsNotExist(err) {
t.Fatalf("Data directory '%s' not found.", dataDir)
}

t.Log("---------------------------------------------------")
t.Log("🌍 CHANGED_FILES not set. Running FULL syntax check on 'data/'...")
t.Log("---------------------------------------------------")

count := 0
err := filepath.Walk(dataDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
count++
validateFile(t, path)
return nil
})

if err != nil {
t.Fatalf("Failed to walk data directory: %v", err)
}
t.Logf("✅ Checked %d files in total.", count)
}
}