github.com/boyter/gocodewalker@v1.3.2/go-gitignore/match_test.go (about) 1 // SPDX-License-Identifier: MIT 2 3 package gitignore_test 4 5 import ( 6 "github.com/boyter/gocodewalker/go-gitignore" 7 "os" 8 "path/filepath" 9 "testing" 10 ) 11 12 func TestMatch(t *testing.T) { 13 // we need to populate a directory with the match test files 14 // - this is to permit GitIgnore.Match() to correctly resolve 15 // absolute path names 16 _dir, _ignore := directory(t) 17 defer os.RemoveAll(_dir) 18 19 // perform the path matching 20 // - first we test absolute paths 21 _cb := func(path string, isdir bool) gitignore.Match { 22 _path := filepath.Join(_dir, path) 23 return _ignore.Match(_path) 24 } 25 for _, _test := range _GITMATCHES { 26 do(t, _cb, _test) 27 } 28 29 // now, attempt relative path matching 30 // - to do this, we need to change the working directory 31 _cwd, _err := os.Getwd() 32 if _err != nil { 33 t.Fatalf("unable to retrieve working directory: %s", _err.Error()) 34 } 35 _err = os.Chdir(_dir) 36 if _err != nil { 37 t.Fatalf("unable to chdir into temporary directory: %s", _err.Error()) 38 } 39 defer func(dir string) { _ = os.Chdir(dir) }(_cwd) 40 41 // perform the relative path tests 42 _cb = func(path string, isdir bool) gitignore.Match { 43 return _ignore.Match(path) 44 } 45 for _, _test := range _GITMATCHES { 46 do(t, _cb, _test) 47 } 48 49 // perform absolute path tests with paths not under the same root 50 // directory as the GitIgnore we are testing 51 _new, _ := directory(t) 52 defer os.RemoveAll(_new) 53 54 for _, _test := range _GITMATCHES { 55 _path := filepath.Join(_new, _test.Local()) 56 _match := _ignore.Match(_path) 57 if _match != nil { 58 t.Fatalf("unexpected match; expected nil, got %v", _match) 59 } 60 } 61 62 // ensure Match() behaves as expected if the absolute path cannot 63 // be determined 64 // - we do this by choosing as our working directory a path 65 // that this process does not have permission to 66 _dir, _err = dir(nil) 67 if _err != nil { 68 t.Fatalf("unable to create temporary directory: %s", _err.Error()) 69 } 70 defer os.RemoveAll(_dir) 71 72 _err = os.Chdir(_dir) 73 if _err != nil { 74 t.Fatalf("unable to chdir into temporary directory: %s", _err.Error()) 75 } 76 defer func(dir string) { _ = os.Chdir(dir) }(_cwd) 77 78 // remove permission from the temporary directory 79 _err = os.Chmod(_dir, 0) 80 if _err != nil { 81 t.Fatalf( 82 "unable to modify temporary directory permissions: %s: %s", 83 _dir, _err.Error(), 84 ) 85 } 86 87 // now perform the match tests and ensure an error is returned 88 for _, _test := range _GITMATCHES { 89 _match := _ignore.Match(_test.Local()) 90 if _match != nil { 91 t.Fatalf("unexpected match; expected nil, got %v", _match) 92 } 93 } 94 } // TestMatch() 95 96 func TestIgnore(t *testing.T) { 97 // we need to populate a directory with the match test files 98 // - this is to permit GitIgnore.Ignore() to correctly resolve 99 // absolute path names 100 _dir, _ignore := directory(t) 101 defer os.RemoveAll(_dir) 102 103 // perform the path matching 104 // - first we test absolute paths 105 for _, _test := range _GITMATCHES { 106 _path := filepath.Join(_dir, _test.Local()) 107 _rtn := _ignore.Ignore(_path) 108 if _rtn != _test.Ignore { 109 t.Errorf( 110 "ignore mismatch for %q; expected %v, got %v", 111 _path, _test.Ignore, _rtn, 112 ) 113 } 114 } 115 116 // now, attempt relative path matching 117 // - to do this, we need to change the working directory 118 _cwd, _err := os.Getwd() 119 if _err != nil { 120 t.Fatalf("unable to retrieve working directory: %s", _err.Error()) 121 } 122 _err = os.Chdir(_dir) 123 if _err != nil { 124 t.Fatalf("unable to chdir into temporary directory: %s", _err.Error()) 125 } 126 defer func(dir string) { _ = os.Chdir(dir) }(_cwd) 127 128 // perform the relative path tests 129 for _, _test := range _GITMATCHES { 130 _rtn := _ignore.Ignore(_test.Local()) 131 if _rtn != _test.Ignore { 132 t.Errorf( 133 "ignore mismatch for %q; expected %v, got %v", 134 _test.Path, _test.Ignore, _rtn, 135 ) 136 } 137 } 138 139 // perform absolute path tests with paths not under the same root 140 // directory as the GitIgnore we are testing 141 _new, _ := directory(t) 142 defer os.RemoveAll(_new) 143 144 for _, _test := range _GITMATCHES { 145 _path := filepath.Join(_new, _test.Local()) 146 _ignore := _ignore.Ignore(_path) 147 if _ignore { 148 t.Fatalf("unexpected ignore for %q", _path) 149 } 150 } 151 } // TestIgnore() 152 153 func TestInclude(t *testing.T) { 154 // we need to populate a directory with the match test files 155 // - this is to permit GitIgnore.Include() to correctly resolve 156 // absolute path names 157 _dir, _ignore := directory(t) 158 defer os.RemoveAll(_dir) 159 160 // perform the path matching 161 // - first we test absolute paths 162 for _, _test := range _GITMATCHES { 163 _path := filepath.Join(_dir, _test.Local()) 164 _rtn := _ignore.Include(_path) 165 if _rtn == _test.Ignore { 166 t.Errorf( 167 "include mismatch for %q; expected %v, got %v", 168 _path, !_test.Ignore, _rtn, 169 ) 170 } 171 } 172 173 // now, attempt relative path matching 174 // - to do this, we need to change the working directory 175 _cwd, _err := os.Getwd() 176 if _err != nil { 177 t.Fatalf("unable to retrieve working directory: %s", _err.Error()) 178 } 179 _err = os.Chdir(_dir) 180 if _err != nil { 181 t.Fatalf("unable to chdir into temporary directory: %s", _err.Error()) 182 } 183 defer func(dir string) { _ = os.Chdir(dir) }(_cwd) 184 185 // perform the relative path tests 186 for _, _test := range _GITMATCHES { 187 _rtn := _ignore.Include(_test.Local()) 188 if _rtn == _test.Ignore { 189 t.Errorf( 190 "include mismatch for %q; expected %v, got %v", 191 _test.Path, !_test.Ignore, _rtn, 192 ) 193 } 194 } 195 196 // perform absolute path tests with paths not under the same root 197 // directory as the GitIgnore we are testing 198 _new, _ := directory(t) 199 defer os.RemoveAll(_new) 200 201 for _, _test := range _GITMATCHES { 202 _path := filepath.Join(_new, _test.Local()) 203 _include := _ignore.Include(_path) 204 if !_include { 205 t.Fatalf("unexpected include for %q", _path) 206 } 207 } 208 } // TestInclude() 209 210 func TestMatchAbsolute(t *testing.T) { 211 // create a temporary .gitignore 212 _buffer, _err := buffer(_GITMATCH) 213 if _err != nil { 214 t.Fatalf("unable to create temporary .gitignore: %s", _err.Error()) 215 } 216 217 // ensure we can run New() 218 // - ensure we encounter no errors 219 _position := []gitignore.Position{} 220 _error := func(e gitignore.Error) bool { 221 _position = append(_position, e.Position()) 222 return true 223 } 224 225 // ensure we have a non-nil GitIgnore instance 226 _ignore := gitignore.New(_buffer, _GITBASE, _error) 227 if _ignore == nil { 228 t.Error("expected non-nil GitIgnore instance; nil found") 229 } 230 231 // ensure we encountered the right number of errors 232 if len(_position) != _GITBADMATCHPATTERNS { 233 t.Errorf( 234 "match error mismatch; expected %d errors, got %d", 235 _GITBADMATCHPATTERNS, len(_position), 236 ) 237 } 238 239 // perform the absolute path matching 240 _cb := func(path string, isdir bool) gitignore.Match { 241 _path := filepath.Join(_GITBASE, path) 242 return _ignore.Absolute(_path, isdir) 243 } 244 for _, _test := range _GITMATCHES { 245 do(t, _cb, _test) 246 } 247 248 // perform absolute path tests with paths not under the same root 249 // directory as the GitIgnore we are testing 250 _new, _ := directory(t) 251 defer os.RemoveAll(_new) 252 253 for _, _test := range _GITMATCHES { 254 _path := filepath.Join(_new, _test.Local()) 255 _match := _ignore.Match(_path) 256 if _match != nil { 257 t.Fatalf("unexpected match; expected nil, got %v", _match) 258 } 259 } 260 } // TestMatchAbsolute() 261 262 func TestMatchRelative(t *testing.T) { 263 // create a temporary .gitignore 264 _buffer, _err := buffer(_GITMATCH) 265 if _err != nil { 266 t.Fatalf("unable to create temporary .gitignore: %s", _err.Error()) 267 } 268 269 // ensure we can run New() 270 // - ensure we encounter no errors 271 _position := []gitignore.Position{} 272 _error := func(e gitignore.Error) bool { 273 _position = append(_position, e.Position()) 274 return true 275 } 276 277 // ensure we have a non-nil GitIgnore instance 278 _ignore := gitignore.New(_buffer, _GITBASE, _error) 279 if _ignore == nil { 280 t.Error("expected non-nil GitIgnore instance; nil found") 281 } 282 283 // ensure we encountered the right number of errors 284 if len(_position) != _GITBADMATCHPATTERNS { 285 t.Errorf( 286 "match error mismatch; expected %d errors, got %d", 287 _GITBADMATCHPATTERNS, len(_position), 288 ) 289 } 290 291 // perform the relative path matching 292 _cb := func(path string, isdir bool) gitignore.Match { 293 return _ignore.Relative(path, isdir) 294 } 295 for _, _test := range _GITMATCHES { 296 do(t, _cb, _test) 297 } 298 } // TestMatchRelative() 299 300 func do(t *testing.T, cb func(string, bool) gitignore.Match, m match) { 301 // attempt to match this path 302 _match := cb(m.Local(), m.IsDir()) 303 if _match == nil { 304 // we have no match, is this expected? 305 // - a test that matches will list the expected pattern 306 if m.Pattern != "" { 307 t.Errorf( 308 "failed match; expected match for %q by %q", 309 m.Path, m.Pattern, 310 ) 311 return 312 } 313 314 // since we have no match, ensure this path is not ignored 315 if m.Ignore { 316 t.Errorf( 317 "failed ignore; no match for %q but expected to be ignored", 318 m.Path, 319 ) 320 } 321 } else { 322 // we have a match, is this expected? 323 // - a test that matches will list the expected pattern 324 if m.Pattern == "" { 325 t.Errorf( 326 "unexpected match by %q; expected no match for %q", 327 _match, m.Path, 328 ) 329 return 330 } else if m.Pattern != _match.String() { 331 t.Errorf( 332 "mismatch for %q; expected match pattern %q, got %q", 333 m.Path, m.Pattern, _match.String(), 334 ) 335 return 336 } 337 338 // since we have a match, are we expected to ignore this file? 339 if m.Ignore != _match.Ignore() { 340 t.Errorf( 341 "ignore mismatch; expected %v for %q Ignore(), "+ 342 "got %v from pattern %q", 343 m.Ignore, m.Path, _match.Ignore(), _match, 344 ) 345 } 346 } 347 } // do() 348 349 func directory(t *testing.T) (string, gitignore.GitIgnore) { 350 // we need to populate a directory with the match test files 351 // - this is to permit GitIgnore.Match() to correctly resolve 352 // absolute path names 353 // - populate the directory by passing a map of file names and their 354 // contents 355 // - the content is not important, it just can't be empty 356 // - use this mechanism to also populate the .gitignore file 357 _map := map[string]string{gitignore.File: _GITMATCH} 358 for _, _test := range _GITMATCHES { 359 _map[_test.Path] = " " // this is the file contents 360 } 361 362 // create the temporary directory 363 _dir, _err := dir(_map) 364 if _err != nil { 365 t.Fatalf("unable to create temporary .gitignore: %s", _err.Error()) 366 } 367 368 // ensure we can run New() 369 // - ensure we encounter no errors 370 _position := []gitignore.Position{} 371 _error := func(e gitignore.Error) bool { 372 _position = append(_position, e.Position()) 373 return true 374 } 375 376 // ensure we have a non-nil GitIgnore instance 377 _file := filepath.Join(_dir, gitignore.File) 378 _ignore := gitignore.NewWithErrors(_file, _error) 379 if _ignore == nil { 380 t.Fatalf("expected non-nil GitIgnore instance; nil found") 381 } 382 383 // ensure we encountered the right number of errors 384 if len(_position) != _GITBADMATCHPATTERNS { 385 t.Errorf( 386 "match error mismatch; expected %d errors, got %d", 387 _GITBADMATCHPATTERNS, len(_position), 388 ) 389 } 390 391 // return the directory name and the GitIgnore instance 392 return _dir, _ignore 393 } // directory()