Add custom types for type safety throughout codebase
- Add FileCount, FileSize, RelFilePath, AbsFilePath, ModTime, Multihash types - Add UnixSeconds and UnixNanos types for timestamp handling - Add URL types (ManifestURL, FileURL, BaseURL) with safe path joining - Consolidate scanner package into mfer package - Update checker to use custom types in Result and CheckStatus - Add ModTime.Timestamp() method for protobuf conversion - Update all tests to use proper custom types
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
package mfer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNewBuilder(t *testing.T) {
|
||||
b := NewBuilder()
|
||||
assert.NotNil(t, b)
|
||||
assert.Equal(t, 0, b.FileCount())
|
||||
}
|
||||
|
||||
func TestBuilderAddFile(t *testing.T) {
|
||||
b := NewBuilder()
|
||||
content := []byte("test content")
|
||||
reader := bytes.NewReader(content)
|
||||
|
||||
bytesRead, err := b.AddFile("test.txt", FileSize(len(content)), ModTime(time.Now()), reader, nil)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, FileSize(len(content)), bytesRead)
|
||||
assert.Equal(t, 1, b.FileCount())
|
||||
}
|
||||
|
||||
func TestBuilderAddFileWithHash(t *testing.T) {
|
||||
b := NewBuilder()
|
||||
hash := make([]byte, 34) // SHA256 multihash is 34 bytes
|
||||
|
||||
err := b.AddFileWithHash("test.txt", 100, ModTime(time.Now()), hash)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 1, b.FileCount())
|
||||
}
|
||||
|
||||
func TestBuilderAddFileWithHashValidation(t *testing.T) {
|
||||
t.Run("empty path", func(t *testing.T) {
|
||||
b := NewBuilder()
|
||||
hash := make([]byte, 34)
|
||||
err := b.AddFileWithHash("", 100, ModTime(time.Now()), hash)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "path")
|
||||
})
|
||||
|
||||
t.Run("negative size", func(t *testing.T) {
|
||||
b := NewBuilder()
|
||||
hash := make([]byte, 34)
|
||||
err := b.AddFileWithHash("test.txt", -1, ModTime(time.Now()), hash)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "size")
|
||||
})
|
||||
|
||||
t.Run("nil hash", func(t *testing.T) {
|
||||
b := NewBuilder()
|
||||
err := b.AddFileWithHash("test.txt", 100, ModTime(time.Now()), nil)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "hash")
|
||||
})
|
||||
|
||||
t.Run("empty hash", func(t *testing.T) {
|
||||
b := NewBuilder()
|
||||
err := b.AddFileWithHash("test.txt", 100, ModTime(time.Now()), []byte{})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "hash")
|
||||
})
|
||||
|
||||
t.Run("valid inputs", func(t *testing.T) {
|
||||
b := NewBuilder()
|
||||
hash := make([]byte, 34)
|
||||
err := b.AddFileWithHash("test.txt", 100, ModTime(time.Now()), hash)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, b.FileCount())
|
||||
})
|
||||
}
|
||||
|
||||
func TestBuilderBuild(t *testing.T) {
|
||||
b := NewBuilder()
|
||||
content := []byte("test content")
|
||||
reader := bytes.NewReader(content)
|
||||
|
||||
_, err := b.AddFile("test.txt", FileSize(len(content)), ModTime(time.Now()), reader, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
var buf bytes.Buffer
|
||||
err = b.Build(&buf)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Should have magic bytes
|
||||
assert.True(t, strings.HasPrefix(buf.String(), MAGIC))
|
||||
}
|
||||
|
||||
func TestBuilderBuildEmpty(t *testing.T) {
|
||||
b := NewBuilder()
|
||||
|
||||
var buf bytes.Buffer
|
||||
err := b.Build(&buf)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Should still produce valid manifest with 0 files
|
||||
assert.True(t, strings.HasPrefix(buf.String(), MAGIC))
|
||||
}
|
||||
Reference in New Issue
Block a user