FastAbs tests

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
This commit is contained in:
Mohammed Al Sahaf 2025-10-21 00:33:57 +03:00
parent 656bfc3111
commit af3d6b3935
No known key found for this signature in database

221
filepath_test.go Normal file
View File

@ -0,0 +1,221 @@
// Copyright 2015 Matthew Holt and The Caddy Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build !windows
package caddy
import (
"path/filepath"
"strings"
"testing"
)
func TestFastAbs(t *testing.T) {
tests := []struct {
name string
input string
checkFunc func(result string, err error) error
}{
{
name: "absolute path",
input: "/usr/local/bin",
checkFunc: func(result string, err error) error {
if err != nil {
t.Errorf("expected no error, got %v", err)
}
if result != "/usr/local/bin" {
t.Errorf("expected /usr/local/bin, got %s", result)
}
return nil
},
},
{
name: "absolute path with dots",
input: "/usr/local/../bin",
checkFunc: func(result string, err error) error {
if err != nil {
t.Errorf("expected no error, got %v", err)
}
if result != "/usr/bin" {
t.Errorf("expected /usr/bin, got %s", result)
}
return nil
},
},
{
name: "relative path",
input: "relative/path",
checkFunc: func(result string, err error) error {
if err != nil {
t.Errorf("expected no error, got %v", err)
}
if !filepath.IsAbs(result) {
t.Errorf("expected absolute path, got %s", result)
}
if !strings.HasSuffix(result, "relative/path") {
t.Errorf("expected path to end with 'relative/path', got %s", result)
}
return nil
},
},
{
name: "dot",
input: ".",
checkFunc: func(result string, err error) error {
if err != nil {
t.Errorf("expected no error, got %v", err)
}
if !filepath.IsAbs(result) {
t.Errorf("expected absolute path, got %s", result)
}
return nil
},
},
{
name: "dot dot",
input: "..",
checkFunc: func(result string, err error) error {
if err != nil {
t.Errorf("expected no error, got %v", err)
}
if !filepath.IsAbs(result) {
t.Errorf("expected absolute path, got %s", result)
}
return nil
},
},
{
name: "empty string",
input: "",
checkFunc: func(result string, err error) error {
if err != nil {
t.Errorf("expected no error, got %v", err)
}
// Empty string should resolve to current directory
if !filepath.IsAbs(result) {
t.Errorf("expected absolute path, got %s", result)
}
return nil
},
},
{
name: "complex relative path",
input: "./foo/../bar/./baz",
checkFunc: func(result string, err error) error {
if err != nil {
t.Errorf("expected no error, got %v", err)
}
if !filepath.IsAbs(result) {
t.Errorf("expected absolute path, got %s", result)
}
if !strings.HasSuffix(result, "bar/baz") {
t.Errorf("expected path to end with 'bar/baz', got %s", result)
}
return nil
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := FastAbs(tt.input)
tt.checkFunc(result, err)
})
}
}
// TestFastAbsVsFilepathAbs compares FastAbs with filepath.Abs to ensure consistent behavior
func TestFastAbsVsFilepathAbs(t *testing.T) {
// Skip if working directory cannot be determined
if wderr != nil {
t.Skip("working directory error, skipping comparison test")
}
testPaths := []string{
".",
"..",
"foo",
"foo/bar",
"./foo",
"../foo",
"/absolute/path",
"/usr/local/bin",
}
for _, path := range testPaths {
t.Run(path, func(t *testing.T) {
fast, fastErr := FastAbs(path)
std, stdErr := filepath.Abs(path)
// Both should succeed or fail together
if (fastErr != nil) != (stdErr != nil) {
t.Errorf("error mismatch: FastAbs=%v, filepath.Abs=%v", fastErr, stdErr)
}
// If both succeed, results should be the same
if fastErr == nil && stdErr == nil && fast != std {
t.Errorf("result mismatch for %q: FastAbs=%s, filepath.Abs=%s", path, fast, std)
}
})
}
}
// TestFastAbsErrorHandling tests error handling when working directory is unavailable
func TestFastAbsErrorHandling(t *testing.T) {
// This tests the cached wderr behavior
if wderr != nil {
// Test that FastAbs properly returns the cached error for relative paths
_, err := FastAbs("relative/path")
if err == nil {
t.Error("expected error for relative path when working directory is unavailable")
}
if err != wderr {
t.Errorf("expected cached wderr, got different error: %v", err)
}
}
}
// BenchmarkFastAbs benchmarks FastAbs
func BenchmarkFastAbs(b *testing.B) {
paths := []string{
"relative/path",
"/absolute/path",
".",
"..",
"./foo/bar",
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
FastAbs(paths[i%len(paths)])
}
}
// BenchmarkFastAbsVsStdLib compares performance of FastAbs vs filepath.Abs
func BenchmarkFastAbsVsStdLib(b *testing.B) {
path := "relative/path/to/file"
b.Run("FastAbs", func(b *testing.B) {
for i := 0; i < b.N; i++ {
FastAbs(path)
}
})
b.Run("filepath.Abs", func(b *testing.B) {
for i := 0; i < b.N; i++ {
filepath.Abs(path)
}
})
}