mirror of
https://github.com/ivuorinen/gibidify.git
synced 2026-01-26 03:24:05 +00:00
feat(tests): more tests and ci action (#14)
* feat(tests): more tests and ci action * fix(ci): coverage and pr-lint * fix(ci): renovate rules, permissions, linting, actions * fix(lint): editorconfig fixes * fix(lint): kics.config * fix(lint): formatting, permissions, pre-commit config * chore(ci): set workflow to use go 1.23, go mod tidy * chore(ci): fixes and stuff * chore(ci): disable GO_GOLANGCI_LINT * chore(ci): pinning, permissions
This commit is contained in:
143
fileproc/walker_test.go
Normal file
143
fileproc/walker_test.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package fileproc
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/ivuorinen/gibidify/config"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func TestProdWalkerWithIgnore(t *testing.T) {
|
||||
// Create a temporary directory structure.
|
||||
rootDir, err := os.MkdirTemp("", "walker_test_root")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp root directory: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(rootDir)
|
||||
|
||||
subDir := filepath.Join(rootDir, "vendor")
|
||||
if err := os.Mkdir(subDir, 0755); err != nil {
|
||||
t.Fatalf("Failed to create subDir: %v", err)
|
||||
}
|
||||
|
||||
// Write sample files
|
||||
filePaths := []string{
|
||||
filepath.Join(rootDir, "file1.go"),
|
||||
filepath.Join(rootDir, "file2.txt"),
|
||||
filepath.Join(subDir, "file_in_vendor.txt"), // should be ignored
|
||||
}
|
||||
for _, fp := range filePaths {
|
||||
if err := os.WriteFile(fp, []byte("content"), 0644); err != nil {
|
||||
t.Fatalf("Failed to write file %s: %v", fp, err)
|
||||
}
|
||||
}
|
||||
|
||||
// .gitignore that ignores *.txt and itself
|
||||
gitignoreContent := `*.txt
|
||||
.gitignore
|
||||
`
|
||||
gitignorePath := filepath.Join(rootDir, ".gitignore")
|
||||
if err := os.WriteFile(gitignorePath, []byte(gitignoreContent), 0644); err != nil {
|
||||
t.Fatalf("Failed to write .gitignore: %v", err)
|
||||
}
|
||||
|
||||
// Initialize config to ignore "vendor" directory
|
||||
viper.Reset()
|
||||
config.LoadConfig()
|
||||
viper.Set("ignoreDirectories", []string{"vendor"})
|
||||
|
||||
// Run walker
|
||||
var w Walker = ProdWalker{}
|
||||
found, err := w.Walk(rootDir)
|
||||
if err != nil {
|
||||
t.Fatalf("Walk returned error: %v", err)
|
||||
}
|
||||
|
||||
// We expect only file1.go to appear
|
||||
if len(found) != 1 {
|
||||
t.Errorf("Expected 1 file to pass filters, got %d: %v", len(found), found)
|
||||
}
|
||||
if len(found) == 1 && filepath.Base(found[0]) != "file1.go" {
|
||||
t.Errorf("Expected file1.go, got %s", found[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestProdWalkerBinaryCheck(t *testing.T) {
|
||||
rootDir, err := os.MkdirTemp("", "walker_test_bincheck")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp root directory: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(rootDir)
|
||||
|
||||
// Create a mock binary file
|
||||
binFile := filepath.Join(rootDir, "somefile.exe")
|
||||
if err := os.WriteFile(binFile, []byte("fake-binary-content"), 0644); err != nil {
|
||||
t.Fatalf("Failed to write file %s: %v", binFile, err)
|
||||
}
|
||||
|
||||
// Create a normal file
|
||||
normalFile := filepath.Join(rootDir, "keep.go")
|
||||
if err := os.WriteFile(normalFile, []byte("package main"), 0644); err != nil {
|
||||
t.Fatalf("Failed to write file %s: %v", normalFile, err)
|
||||
}
|
||||
|
||||
// Reset and load default config
|
||||
viper.Reset()
|
||||
config.LoadConfig()
|
||||
|
||||
// Run walker
|
||||
var w Walker = ProdWalker{}
|
||||
found, err := w.Walk(rootDir)
|
||||
if err != nil {
|
||||
t.Fatalf("Walk returned error: %v", err)
|
||||
}
|
||||
|
||||
// Only "keep.go" should be returned
|
||||
if len(found) != 1 {
|
||||
t.Errorf("Expected 1 file, got %d: %v", len(found), found)
|
||||
}
|
||||
if len(found) == 1 && filepath.Base(found[0]) != "keep.go" {
|
||||
t.Errorf("Expected keep.go in results, got %s", found[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestProdWalkerSizeLimit(t *testing.T) {
|
||||
rootDir, err := os.MkdirTemp("", "walker_test_sizelimit")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp root directory: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(rootDir)
|
||||
|
||||
// Create a file exceeding the size limit
|
||||
largeFilePath := filepath.Join(rootDir, "largefile.txt")
|
||||
largeFileData := make([]byte, 6*1024*1024) // 6 MB
|
||||
if err := os.WriteFile(largeFilePath, largeFileData, 0644); err != nil {
|
||||
t.Fatalf("Failed to write large file: %v", err)
|
||||
}
|
||||
|
||||
// Create a small file
|
||||
smallFilePath := filepath.Join(rootDir, "smallfile.go")
|
||||
if err := os.WriteFile(smallFilePath, []byte("package main"), 0644); err != nil {
|
||||
t.Fatalf("Failed to write small file: %v", err)
|
||||
}
|
||||
|
||||
// Reset and load default config, which sets size limit to 5 MB
|
||||
viper.Reset()
|
||||
config.LoadConfig()
|
||||
|
||||
var w Walker = ProdWalker{}
|
||||
found, err := w.Walk(rootDir)
|
||||
if err != nil {
|
||||
t.Fatalf("Walk returned error: %v", err)
|
||||
}
|
||||
|
||||
// We should only get the small file
|
||||
if len(found) != 1 {
|
||||
t.Errorf("Expected 1 file under size limit, got %d", len(found))
|
||||
}
|
||||
if len(found) == 1 && filepath.Base(found[0]) != "smallfile.go" {
|
||||
t.Errorf("Expected smallfile.go, got %s", found[0])
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,10 @@
|
||||
// Package fileproc provides a writer for the output of the file processor.
|
||||
//
|
||||
// The StartWriter function writes the output in the specified format.
|
||||
// The formatMarkdown function formats the output in Markdown format.
|
||||
// The detectLanguage function tries to infer the code block language from the file extension.
|
||||
// The OutputData struct represents the full output structure.
|
||||
// The FileData struct represents a single file's path and content.
|
||||
package fileproc
|
||||
|
||||
import (
|
||||
@@ -28,7 +35,7 @@ func StartWriter(outFile *os.File, writeCh <-chan WriteRequest, done chan<- stru
|
||||
|
||||
// Read from channel until closed
|
||||
for req := range writeCh {
|
||||
files = append(files, FileData{Path: req.Path, Content: req.Content})
|
||||
files = append(files, FileData(req))
|
||||
}
|
||||
|
||||
// Create output struct
|
||||
|
||||
@@ -3,43 +3,117 @@ package fileproc
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func TestStartWriter_JSONOutput(t *testing.T) {
|
||||
outFile, err := os.CreateTemp("", "output.json")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func(name string) {
|
||||
err := os.Remove(name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}(outFile.Name())
|
||||
|
||||
writeCh := make(chan WriteRequest)
|
||||
done := make(chan struct{})
|
||||
|
||||
go StartWriter(outFile, writeCh, done, "json", "Prefix", "Suffix")
|
||||
|
||||
writeCh <- WriteRequest{Path: "file1.go", Content: "package main"}
|
||||
writeCh <- WriteRequest{Path: "file2.py", Content: "def hello(): print('Hello')"}
|
||||
|
||||
close(writeCh)
|
||||
<-done
|
||||
|
||||
data, err := os.ReadFile(outFile.Name())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
func TestStartWriter_Formats(t *testing.T) {
|
||||
// Define table-driven test cases
|
||||
tests := []struct {
|
||||
name string
|
||||
format string
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
name: "JSON format",
|
||||
format: "json",
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "YAML format",
|
||||
format: "yaml",
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "Markdown format",
|
||||
format: "markdown",
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "Invalid format",
|
||||
format: "invalid",
|
||||
expectError: true,
|
||||
},
|
||||
}
|
||||
|
||||
var output OutputData
|
||||
if err := json.Unmarshal(data, &output); err != nil {
|
||||
t.Fatalf("JSON output is invalid: %v", err)
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
outFile, err := os.CreateTemp("", "gibidify_test_output")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp file: %v", err)
|
||||
}
|
||||
defer func() {
|
||||
outFile.Close()
|
||||
os.Remove(outFile.Name())
|
||||
}()
|
||||
|
||||
if len(output.Files) != 2 {
|
||||
t.Errorf("Expected 2 files, got %d", len(output.Files))
|
||||
// Prepare channels
|
||||
writeCh := make(chan WriteRequest, 2)
|
||||
doneCh := make(chan struct{})
|
||||
|
||||
// Write a couple of sample requests
|
||||
writeCh <- WriteRequest{Path: "sample.go", Content: "package main"}
|
||||
writeCh <- WriteRequest{Path: "example.py", Content: "def foo(): pass"}
|
||||
close(writeCh)
|
||||
|
||||
// Start the writer
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
StartWriter(outFile, writeCh, doneCh, tc.format, "PREFIX", "SUFFIX")
|
||||
}()
|
||||
|
||||
// Wait until writer signals completion
|
||||
wg.Wait()
|
||||
<-doneCh // make sure all writes finished
|
||||
|
||||
// Read output
|
||||
data, err := os.ReadFile(outFile.Name())
|
||||
if err != nil {
|
||||
t.Fatalf("Error reading output file: %v", err)
|
||||
}
|
||||
|
||||
if tc.expectError {
|
||||
// For an invalid format, we expect StartWriter to log an error
|
||||
// and produce no content or minimal content. There's no official
|
||||
// error returned, so check if it's empty or obviously incorrect.
|
||||
if len(data) != 0 {
|
||||
t.Errorf("Expected no output for invalid format, got:\n%s", data)
|
||||
}
|
||||
} else {
|
||||
// Valid format: check basic properties in the output
|
||||
content := string(data)
|
||||
switch tc.format {
|
||||
case "json":
|
||||
// Quick parse check
|
||||
var outStruct OutputData
|
||||
if err := json.Unmarshal(data, &outStruct); err != nil {
|
||||
t.Errorf("JSON unmarshal failed: %v", err)
|
||||
}
|
||||
case "yaml":
|
||||
var outStruct OutputData
|
||||
if err := yaml.Unmarshal(data, &outStruct); err != nil {
|
||||
t.Errorf("YAML unmarshal failed: %v", err)
|
||||
}
|
||||
case "markdown":
|
||||
// Check presence of code fences or "## File: ..."
|
||||
if !strings.Contains(content, "```") {
|
||||
t.Error("Expected markdown code fences not found")
|
||||
}
|
||||
}
|
||||
|
||||
// Prefix and suffix checks (common to JSON, YAML, markdown)
|
||||
if !strings.Contains(string(data), "PREFIX") {
|
||||
t.Errorf("Missing prefix in output: %s", data)
|
||||
}
|
||||
if !strings.Contains(string(data), "SUFFIX") {
|
||||
t.Errorf("Missing suffix in output: %s", data)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user