Files
gibidify/testutil/config_test.go
Ismo Vuorinen 95b7ef6dd3 chore: modernize workflows, security scanning, and linting configuration (#50)
* build: update Go 1.25, CI workflows, and build tooling

- Upgrade to Go 1.25
- Add benchmark targets to Makefile
- Implement parallel gosec execution
- Lock tool versions for reproducibility
- Add shellcheck directives to scripts
- Update CI workflows with improved caching

* refactor: migrate from golangci-lint to revive

- Replace golangci-lint with revive for linting
- Configure comprehensive revive rules
- Fix all EditorConfig violations
- Add yamllint and yamlfmt support
- Remove deprecated .golangci.yml

* refactor: rename utils to shared and deduplicate code

- Rename utils package to shared
- Add shared constants package
- Deduplicate constants across packages
- Address CodeRabbit review feedback

* fix: resolve SonarQube issues and add safety guards

- Fix all 73 SonarQube OPEN issues
- Add nil guards for resourceMonitor, backpressure, metricsCollector
- Implement io.Closer for headerFileReader
- Propagate errors from processing helpers
- Add metrics and templates packages
- Improve error handling across codebase

* test: improve test infrastructure and coverage

- Add benchmarks for cli, fileproc, metrics
- Improve test coverage for cli, fileproc, config
- Refactor tests with helper functions
- Add shared test constants
- Fix test function naming conventions
- Reduce cognitive complexity in benchmark tests

* docs: update documentation and configuration examples

- Update CLAUDE.md with current project state
- Refresh README with new features
- Add usage and configuration examples
- Add SonarQube project configuration
- Consolidate config.example.yaml

* fix: resolve shellcheck warnings in scripts

- Use ./*.go instead of *.go to prevent dash-prefixed filenames
  from being interpreted as options (SC2035)
- Remove unreachable return statement after exit (SC2317)
- Remove obsolete gibidiutils/ directory reference

* chore(deps): upgrade go dependencies

* chore(lint): megalinter fixes

* fix: improve test coverage and fix file descriptor leaks

- Add defer r.Close() to fix pipe file descriptor leaks in benchmark tests
- Refactor TestProcessorConfigureFileTypes with helper functions and assertions
- Refactor TestProcessorLogFinalStats with output capture and keyword verification
- Use shared constants instead of literal strings (TestFilePNG, FormatMarkdown, etc.)
- Reduce cognitive complexity by extracting helper functions

* fix: align test comments with function names

Remove underscores from test comments to match actual function names:
- benchmark/benchmark_test.go (2 fixes)
- fileproc/filetypes_config_test.go (4 fixes)
- fileproc/filetypes_registry_test.go (6 fixes)
- fileproc/processor_test.go (6 fixes)
- fileproc/resource_monitor_types_test.go (4 fixes)
- fileproc/writer_test.go (3 fixes)

* fix: various test improvements and bug fixes

- Remove duplicate maxCacheSize check in filetypes_registry_test.go
- Shorten long comment in processor_test.go to stay under 120 chars
- Remove flaky time.Sleep in collector_test.go, use >= 0 assertion
- Close pipe reader in benchmark_test.go to fix file descriptor leak
- Use ContinueOnError in flags_test.go to match ResetFlags behavior
- Add nil check for p.ui in processor_workers.go before UpdateProgress
- Fix resource_monitor_validation_test.go by setting hardMemoryLimitBytes directly

* chore(yaml): add missing document start markers

Add --- document start to YAML files to satisfy yamllint:
- .github/workflows/codeql.yml
- .github/workflows/build-test-publish.yml
- .github/workflows/security.yml
- .github/actions/setup/action.yml

* fix: guard nil resourceMonitor and fix test deadlock

- Guard resourceMonitor before CreateFileProcessingContext call
- Add ui.UpdateProgress on emergency stop and path error returns
- Fix potential deadlock in TestProcessFile using wg.Go with defer close
2025-12-10 19:07:11 +02:00

152 lines
3.3 KiB
Go

package testutil
import (
"os"
"testing"
"github.com/spf13/viper"
"github.com/ivuorinen/gibidify/shared"
)
func TestResetViperConfig(t *testing.T) {
tests := []struct {
name string
configPath string
preSetup func()
verify func(t *testing.T)
}{
{
name: "reset with empty config path",
configPath: "",
preSetup: func() {
viper.Set(shared.TestKeyName, "value")
},
verify: func(t *testing.T) {
t.Helper()
if viper.IsSet(shared.TestKeyName) {
t.Error("Viper config not reset properly")
}
},
},
{
name: "reset with config path",
configPath: t.TempDir(),
preSetup: func() {
viper.Set(shared.TestKeyName, "value")
},
verify: func(t *testing.T) {
t.Helper()
if viper.IsSet(shared.TestKeyName) {
t.Error("Viper config not reset properly")
}
// Verify config path was added
paths := viper.ConfigFileUsed()
if paths == "" {
// This is expected as no config file exists
return
}
},
},
}
for _, tt := range tests {
t.Run(
tt.name, func(t *testing.T) {
tt.preSetup()
ResetViperConfig(t, tt.configPath)
tt.verify(t)
},
)
}
}
func TestSetupCLIArgs(t *testing.T) {
// Save original args
originalArgs := os.Args
defer func() {
os.Args = originalArgs
}()
tests := []struct {
name string
srcDir string
outFile string
prefix string
suffix string
concurrency int
wantLen int
}{
{
name: "basic CLI args",
srcDir: "/src",
outFile: "/out.txt",
prefix: "PREFIX",
suffix: "SUFFIX",
concurrency: 4,
wantLen: 12,
},
{
name: "empty strings",
srcDir: "",
outFile: "",
prefix: "",
suffix: "",
concurrency: 1,
wantLen: 12,
},
{
name: "special characters in args",
srcDir: "/path with spaces/src",
outFile: "/path/to/output file.txt",
prefix: "Prefix with\nnewline",
suffix: "Suffix with\ttab",
concurrency: 8,
wantLen: 12,
},
}
for _, tt := range tests {
t.Run(
tt.name, func(t *testing.T) {
SetupCLIArgs(tt.srcDir, tt.outFile, tt.prefix, tt.suffix, tt.concurrency)
verifySetupCLIArgs(t, tt.srcDir, tt.outFile, tt.prefix, tt.suffix, tt.concurrency, tt.wantLen)
},
)
}
}
// verifySetupCLIArgs verifies that CLI arguments are set correctly.
func verifySetupCLIArgs(t *testing.T, srcDir, outFile, prefix, suffix string, concurrency, wantLen int) {
t.Helper()
if len(os.Args) != wantLen {
t.Errorf("os.Args length = %d, want %d", len(os.Args), wantLen)
}
// Verify specific args
if os.Args[0] != "gibidify" {
t.Errorf("Program name = %s, want gibidify", os.Args[0])
}
if os.Args[2] != srcDir {
t.Errorf("Source dir = %s, want %s", os.Args[2], srcDir)
}
if os.Args[4] != outFile {
t.Errorf("Output file = %s, want %s", os.Args[4], outFile)
}
if os.Args[6] != prefix {
t.Errorf("Prefix = %s, want %s", os.Args[6], prefix)
}
if os.Args[8] != suffix {
t.Errorf("Suffix = %s, want %s", os.Args[8], suffix)
}
if os.Args[10] != string(rune(concurrency+'0')) {
t.Errorf("Concurrency = %s, want %d", os.Args[10], concurrency)
}
// Verify the -no-ui flag is present
if os.Args[11] != "-no-ui" {
t.Errorf("NoUI flag = %s, want -no-ui", os.Args[11])
}
}