fs: fix filename normalization issues in the tests when running on OS X

This commit is contained in:
Nick Craig-Wood 2017-09-17 14:05:33 +01:00
parent 12405f9f41
commit 87335de8a8
3 changed files with 35 additions and 13 deletions

View file

@ -3,6 +3,7 @@
package fs_test package fs_test
import ( import (
"runtime"
"testing" "testing"
"time" "time"
@ -965,6 +966,10 @@ func TestSyncBackupDirWithSuffix(t *testing.T) { testSyncBackupDir(t, ".bak") }
// Check we can sync two files with differing UTF-8 representations // Check we can sync two files with differing UTF-8 representations
func TestSyncUTFNorm(t *testing.T) { func TestSyncUTFNorm(t *testing.T) {
if runtime.GOOS == "darwin" {
t.Skip("Can't test UTF normalization on OS X")
}
r := NewRun(t) r := NewRun(t)
defer r.Finalise() defer r.Finalise()

View file

@ -15,6 +15,7 @@ import (
"path" "path"
"path/filepath" "path/filepath"
"regexp" "regexp"
"runtime"
"sort" "sort"
"strings" "strings"
"testing" "testing"
@ -23,6 +24,7 @@ import (
"github.com/ncw/rclone/fs" "github.com/ncw/rclone/fs"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"golang.org/x/text/unicode/norm"
) )
// Globals // Globals
@ -124,6 +126,16 @@ func (i *Item) Check(t *testing.T, obj fs.Object, precision time.Duration) {
i.CheckModTime(t, obj, obj.ModTime(), precision) i.CheckModTime(t, obj, obj.ModTime(), precision)
} }
// Normalize runs a utf8 normalization on the string if running on OS
// X. This is because OS X denormalizes file names it writes to the
// local file system.
func Normalize(name string) string {
if runtime.GOOS == "darwin" {
name = norm.NFC.String(name)
}
return name
}
// Items represents all items for checking // Items represents all items for checking
type Items struct { type Items struct {
byName map[string]*Item byName map[string]*Item
@ -140,18 +152,19 @@ func NewItems(items []Item) *Items {
} }
// Fill up byName // Fill up byName
for i := range items { for i := range items {
is.byName[items[i].Path] = &items[i] is.byName[Normalize(items[i].Path)] = &items[i]
is.byNameAlt[items[i].WinPath] = &items[i] is.byNameAlt[Normalize(items[i].WinPath)] = &items[i]
} }
return is return is
} }
// Find checks off an item // Find checks off an item
func (is *Items) Find(t *testing.T, obj fs.Object, precision time.Duration) { func (is *Items) Find(t *testing.T, obj fs.Object, precision time.Duration) {
i, ok := is.byName[obj.Remote()] remote := Normalize(obj.Remote())
i, ok := is.byName[remote]
if !ok { if !ok {
i, ok = is.byNameAlt[obj.Remote()] i, ok = is.byNameAlt[remote]
assert.True(t, ok, fmt.Sprintf("Unexpected file %q", obj.Remote())) assert.True(t, ok, fmt.Sprintf("Unexpected file %q", remote))
} }
if i != nil { if i != nil {
delete(is.byName, i.Path) delete(is.byName, i.Path)
@ -177,8 +190,8 @@ func makeListingFromItems(items []Item) (string, string) {
nameLengths1 := make([]string, len(items)) nameLengths1 := make([]string, len(items))
nameLengths2 := make([]string, len(items)) nameLengths2 := make([]string, len(items))
for i, item := range items { for i, item := range items {
remote1 := item.Path remote1 := Normalize(item.Path)
remote2 := item.Path remote2 := remote1
if item.WinPath != "" { if item.WinPath != "" {
remote2 = item.WinPath remote2 = item.WinPath
} }
@ -194,7 +207,7 @@ func makeListingFromItems(items []Item) (string, string) {
func makeListingFromObjects(objs []fs.Object) string { func makeListingFromObjects(objs []fs.Object) string {
nameLengths := make([]string, len(objs)) nameLengths := make([]string, len(objs))
for i, obj := range objs { for i, obj := range objs {
nameLengths[i] = fmt.Sprintf("%s (%d)", obj.Remote(), obj.Size()) nameLengths[i] = fmt.Sprintf("%s (%d)", Normalize(obj.Remote()), obj.Size())
} }
sort.Strings(nameLengths) sort.Strings(nameLengths)
return strings.Join(nameLengths, ", ") return strings.Join(nameLengths, ", ")
@ -281,13 +294,17 @@ func CheckListingWithPrecision(t *testing.T, f fs.Fs, items []Item, expectedDirs
} }
// Check the directories // Check the directories
if expectedDirs != nil { if expectedDirs != nil {
expectedDirsCopy := make([]string, len(expectedDirs))
for i, dir := range expectedDirs {
expectedDirsCopy[i] = Normalize(dir)
}
actualDirs := []string{} actualDirs := []string{}
for _, dir := range dirs { for _, dir := range dirs {
actualDirs = append(actualDirs, dir.Remote()) actualDirs = append(actualDirs, Normalize(dir.Remote()))
} }
sort.Strings(actualDirs) sort.Strings(actualDirs)
sort.Strings(expectedDirs) sort.Strings(expectedDirsCopy)
assert.Equal(t, expectedDirs, actualDirs, "directories") assert.Equal(t, expectedDirsCopy, actualDirs, "directories")
} }
} }

View file

@ -217,7 +217,7 @@ func winPath(s string) string {
func dirsToNames(dirs []fs.Directory) []string { func dirsToNames(dirs []fs.Directory) []string {
names := []string{} names := []string{}
for _, dir := range dirs { for _, dir := range dirs {
names = append(names, winPath(dir.Remote())) names = append(names, winPath(fstest.Normalize(dir.Remote())))
} }
sort.Strings(names) sort.Strings(names)
return names return names
@ -227,7 +227,7 @@ func dirsToNames(dirs []fs.Directory) []string {
func objsToNames(objs []fs.Object) []string { func objsToNames(objs []fs.Object) []string {
names := []string{} names := []string{}
for _, obj := range objs { for _, obj := range objs {
names = append(names, winPath(obj.Remote())) names = append(names, winPath(fstest.Normalize(obj.Remote())))
} }
sort.Strings(names) sort.Strings(names)
return names return names