github.com/rclone/rclone@v1.66.1-0.20240517100346-7b89735ae726/fs/filter/glob_test.go (about)

     1  package filter
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/assert"
     7  	"github.com/stretchr/testify/require"
     8  )
     9  
    10  func TestGlobToRegexp(t *testing.T) {
    11  	for _, test := range []struct {
    12  		in    string
    13  		want  string
    14  		error string
    15  	}{
    16  		{``, `(^|/)$`, ``},
    17  		{`potato`, `(^|/)potato$`, ``},
    18  		{`potato,sausage`, `(^|/)potato,sausage$`, ``},
    19  		{`/potato`, `^potato$`, ``},
    20  		{`potato?sausage`, `(^|/)potato[^/]sausage$`, ``},
    21  		{`potat[oa]`, `(^|/)potat[oa]$`, ``},
    22  		{`potat[a-z]or`, `(^|/)potat[a-z]or$`, ``},
    23  		{`potat[[:alpha:]]or`, `(^|/)potat[[:alpha:]]or$`, ``},
    24  		{`'.' '+' '(' ')' '|' '^' '$'`, `(^|/)'\.' '\+' '\(' '\)' '\|' '\^' '\$'$`, ``},
    25  		{`*.jpg`, `(^|/)[^/]*\.jpg$`, ``},
    26  		{`a{b,c,d}e`, `(^|/)a(b|c|d)e$`, ``},
    27  		{`potato**`, `(^|/)potato.*$`, ``},
    28  		{`potato**sausage`, `(^|/)potato.*sausage$`, ``},
    29  		{`*.p[lm]`, `(^|/)[^/]*\.p[lm]$`, ``},
    30  		{`[\[\]]`, `(^|/)[\[\]]$`, ``},
    31  		{`***potato`, `(^|/)`, `too many stars`},
    32  		{`***`, `(^|/)`, `too many stars`},
    33  		{`ab]c`, `(^|/)`, `mismatched ']'`},
    34  		{`ab[c`, `(^|/)`, `mismatched '[' and ']'`},
    35  		{`ab{x{cd`, `(^|/)`, `can't nest`},
    36  		{`ab{}}cd`, `(^|/)`, `mismatched '{' and '}'`},
    37  		{`ab}c`, `(^|/)`, `mismatched '{' and '}'`},
    38  		{`ab{c`, `(^|/)`, `mismatched '{' and '}'`},
    39  		{`*.{jpg,png,gif}`, `(^|/)[^/]*\.(jpg|png|gif)$`, ``},
    40  		{`[a--b]`, `(^|/)`, `bad glob pattern`},
    41  		{`a\*b`, `(^|/)a\*b$`, ``},
    42  		{`a\\b`, `(^|/)a\\b$`, ``},
    43  		{`a{{.*}}b`, `(^|/)a(.*)b$`, ``},
    44  		{`a{{.*}`, `(^|/)a(.*)b$`, `mismatched '{{' and '}}'`},
    45  		{`{{regexp}}`, `(^|/)(regexp)$`, ``},
    46  		{`\{{{regexp}}`, `(^|/)\{(regexp)$`, ``},
    47  		{`/{{regexp}}`, `^(regexp)$`, ``},
    48  		{`/{{\d{8}}}`, `^(\d{8})$`, ``},
    49  		{`/{{\}}}`, `^(\})$`, ``},
    50  		{`{{(?i)regexp}}`, `(^|/)((?i)regexp)$`, ``},
    51  	} {
    52  		for _, ignoreCase := range []bool{false, true} {
    53  			gotRe, err := GlobToRegexp(test.in, ignoreCase)
    54  			if test.error == "" {
    55  				require.NoError(t, err, test.in)
    56  				prefix := ""
    57  				if ignoreCase {
    58  					prefix = "(?i)"
    59  				}
    60  				got := gotRe.String()
    61  				assert.Equal(t, prefix+test.want, got, test.in)
    62  			} else {
    63  				require.Error(t, err, test.in)
    64  				assert.Contains(t, err.Error(), test.error, test.in)
    65  				assert.Nil(t, gotRe)
    66  			}
    67  		}
    68  	}
    69  }
    70  
    71  func TestGlobToDirGlobs(t *testing.T) {
    72  	for _, test := range []struct {
    73  		in   string
    74  		want []string
    75  	}{
    76  		{`*`, []string{"/**"}},
    77  		{`/*`, []string{"/"}},
    78  		{`*.jpg`, []string{"/**"}},
    79  		{`/*.jpg`, []string{"/"}},
    80  		{`//*.jpg`, []string{"/"}},
    81  		{`///*.jpg`, []string{"/"}},
    82  		{`/a/*.jpg`, []string{"/a/", "/"}},
    83  		{`/a//*.jpg`, []string{"/a/", "/"}},
    84  		{`/a///*.jpg`, []string{"/a/", "/"}},
    85  		{`/a/b/*.jpg`, []string{"/a/b/", "/a/", "/"}},
    86  		{`a/*.jpg`, []string{"a/"}},
    87  		{`a/b/*.jpg`, []string{"a/b/", "a/"}},
    88  		{`*/*/*.jpg`, []string{"*/*/", "*/"}},
    89  		{`a/b/`, []string{"a/b/", "a/"}},
    90  		{`a/b`, []string{"a/"}},
    91  		{`a/b/*.{jpg,png,gif}`, []string{"a/b/", "a/"}},
    92  		{`/a/{jpg,png,gif}/*.{jpg,png,gif}`, []string{"/a/{jpg,png,gif}/", "/a/", "/"}},
    93  		{`a/{a,a*b,a**c}/d/`, []string{"/**"}},
    94  		{`/a/{a,a*b,a/c,d}/d/`, []string{"/**"}},
    95  		{`/a/{{.*}}/d/`, []string{"/**"}},
    96  		{`**`, []string{"**/"}},
    97  		{`a**`, []string{"a**/"}},
    98  		{`a**b`, []string{"a**/"}},
    99  		{`a**b**c**d`, []string{"a**b**c**/", "a**b**/", "a**/"}},
   100  		{`a**b/c**d`, []string{"a**b/c**/", "a**b/", "a**/"}},
   101  		{`/A/a**b/B/c**d/C/`, []string{"/A/a**b/B/c**d/C/", "/A/a**b/B/c**d/", "/A/a**b/B/c**/", "/A/a**b/B/", "/A/a**b/", "/A/a**/", "/A/", "/"}},
   102  		{`/var/spool/**/ncw`, []string{"/var/spool/**/", "/var/spool/", "/var/", "/"}},
   103  		{`var/spool/**/ncw/`, []string{"var/spool/**/ncw/", "var/spool/**/", "var/spool/", "var/"}},
   104  		{"/file1.jpg", []string{`/`}},
   105  		{"/file2.png", []string{`/`}},
   106  		{"/*.jpg", []string{`/`}},
   107  		{"/*.png", []string{`/`}},
   108  		{"/potato", []string{`/`}},
   109  		{"/sausage1", []string{`/`}},
   110  		{"/sausage2*", []string{`/`}},
   111  		{"/sausage3**", []string{`/sausage3**/`, "/"}},
   112  		{"/a/*.jpg", []string{`/a/`, "/"}},
   113  	} {
   114  		_, err := GlobToRegexp(test.in, false)
   115  		assert.NoError(t, err)
   116  		got := globToDirGlobs(test.in)
   117  		assert.Equal(t, test.want, got, test.in)
   118  	}
   119  }