|
|
@@ -15,10 +15,12 @@ import (
|
|
|
"net"
|
|
|
"os"
|
|
|
"path/filepath"
|
|
|
+ "runtime"
|
|
|
"strconv"
|
|
|
"testing"
|
|
|
"time"
|
|
|
|
|
|
+ "github.com/d4l3k/messagediff"
|
|
|
"github.com/syncthing/syncthing/lib/config"
|
|
|
"github.com/syncthing/syncthing/lib/db"
|
|
|
"github.com/syncthing/syncthing/lib/protocol"
|
|
|
@@ -1210,3 +1212,89 @@ func TestIgnoreDelete(t *testing.T) {
|
|
|
t.Fatal("foo should not be marked for deletion")
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+func TestUnifySubs(t *testing.T) {
|
|
|
+ cases := []struct {
|
|
|
+ in []string // input to unifySubs
|
|
|
+ exists []string // paths that exist in the database
|
|
|
+ out []string // expected output
|
|
|
+ }{
|
|
|
+ {
|
|
|
+ // trailing slashes are cleaned, known paths are just passed on
|
|
|
+ []string{"foo/", "bar//"},
|
|
|
+ []string{"foo", "bar"},
|
|
|
+ []string{"bar", "foo"}, // the output is sorted
|
|
|
+ },
|
|
|
+ {
|
|
|
+ // "foo/bar" gets trimmed as it's covered by foo
|
|
|
+ []string{"foo", "bar/", "foo/bar/"},
|
|
|
+ []string{"foo", "bar"},
|
|
|
+ []string{"bar", "foo"},
|
|
|
+ },
|
|
|
+ {
|
|
|
+ // "bar" gets trimmed to "" as it's unknown,
|
|
|
+ // "" gets simplified to the empty list
|
|
|
+ []string{"foo", "bar", "foo/bar"},
|
|
|
+ []string{"foo"},
|
|
|
+ nil,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ // two independent known paths, both are kept
|
|
|
+ // "usr/lib" is not a prefix of "usr/libexec"
|
|
|
+ []string{"usr/lib", "usr/libexec"},
|
|
|
+ []string{"usr/lib", "usr/libexec"},
|
|
|
+ []string{"usr/lib", "usr/libexec"},
|
|
|
+ },
|
|
|
+ {
|
|
|
+ // "usr/lib" is a prefix of "usr/lib/exec"
|
|
|
+ []string{"usr/lib", "usr/lib/exec"},
|
|
|
+ []string{"usr/lib", "usr/libexec"},
|
|
|
+ []string{"usr/lib"},
|
|
|
+ },
|
|
|
+ {
|
|
|
+ // .stignore and .stfolder are special and are passed on
|
|
|
+ // verbatim even though they are unknown
|
|
|
+ []string{".stfolder", ".stignore"},
|
|
|
+ []string{},
|
|
|
+ []string{".stfolder", ".stignore"},
|
|
|
+ },
|
|
|
+ {
|
|
|
+ // but the presense of something else unknown forces an actual
|
|
|
+ // scan
|
|
|
+ []string{".stfolder", ".stignore", "foo/bar"},
|
|
|
+ []string{},
|
|
|
+ nil,
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ if runtime.GOOS == "windows" {
|
|
|
+ // Fixup path separators
|
|
|
+ for i := range cases {
|
|
|
+ for j, p := range cases[i].in {
|
|
|
+ cases[i].in[j] = filepath.FromSlash(p)
|
|
|
+ }
|
|
|
+ for j, p := range cases[i].exists {
|
|
|
+ cases[i].exists[j] = filepath.FromSlash(p)
|
|
|
+ }
|
|
|
+ for j, p := range cases[i].out {
|
|
|
+ cases[i].out[j] = filepath.FromSlash(p)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for i, tc := range cases {
|
|
|
+ exists := func(f string) bool {
|
|
|
+ for _, e := range tc.exists {
|
|
|
+ if f == e {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ out := unifySubs(tc.in, exists)
|
|
|
+ if diff, equal := messagediff.PrettyDiff(tc.out, out); !equal {
|
|
|
+ t.Errorf("Case %d failed; got %v, expected %v, diff:\n%s", i, out, tc.out, diff)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|