github.com/LambdaTest/go-gitignore@v0.0.0-20230214141342-7fe15342e580/gitignore_test.go (about) 1 package gitignore_test 2 3 import ( 4 "testing" 5 6 "os" 7 "path/filepath" 8 9 "github.com/denormal/go-gitignore" 10 ) 11 12 type gitignoretest struct { 13 errors []gitignore.Error 14 error func(gitignore.Error) bool 15 cache gitignore.Cache 16 cached bool 17 instance func(string) (gitignore.GitIgnore, error) 18 } // gitignoretest{} 19 20 func TestNewFromFile(t *testing.T) { 21 _test := &gitignoretest{} 22 _test.instance = func(file string) (gitignore.GitIgnore, error) { 23 return gitignore.NewFromFile(file) 24 } 25 26 // perform the gitignore test 27 withfile(t, _test, _GITIGNORE) 28 } // TestNewFromFile() 29 30 func TestNewFromWhitespaceFile(t *testing.T) { 31 _test := &gitignoretest{} 32 _test.instance = func(file string) (gitignore.GitIgnore, error) { 33 return gitignore.NewFromFile(file) 34 } 35 36 // perform the gitignore test 37 withfile(t, _test, _GITIGNORE_WHITESPACE) 38 } // TestNewFromWhitespaceFile() 39 40 func TestNewFromEmptyFile(t *testing.T) { 41 _test := &gitignoretest{} 42 _test.instance = func(file string) (gitignore.GitIgnore, error) { 43 return gitignore.NewFromFile(file) 44 } 45 46 // perform the gitignore test 47 withfile(t, _test, "") 48 } // TestNewFromEmptyFile() 49 50 func TestNewWithErrors(t *testing.T) { 51 _test := &gitignoretest{} 52 _test.error = func(e gitignore.Error) bool { 53 _test.errors = append(_test.errors, e) 54 return true 55 } 56 _test.instance = func(file string) (gitignore.GitIgnore, error) { 57 // reset the error slice 58 _test.errors = make([]gitignore.Error, 0) 59 60 // attempt to create the GitIgnore instance 61 _ignore := gitignore.NewWithErrors(file, _test.error) 62 63 // if we encountered errors, and the first error has a zero position 64 // then it represents a file access error 65 // - extract the error and return it 66 // - remove it from the list of errors 67 var _err error 68 if len(_test.errors) > 0 { 69 if _test.errors[0].Position().Zero() { 70 _err = _test.errors[0].Underlying() 71 _test.errors = _test.errors[1:] 72 } 73 } 74 75 // return the GitIgnore instance 76 return _ignore, _err 77 } 78 79 // perform the gitignore test 80 withfile(t, _test, _GITIGNORE) 81 82 _test.error = nil 83 withfile(t, _test, _GITIGNORE) 84 } // TestNewWithErrors() 85 86 func TestNewWithCache(t *testing.T) { 87 // perform the gitignore test with a custom cache 88 _test := &gitignoretest{} 89 _test.cached = true 90 _test.cache = gitignore.NewCache() 91 _test.instance = func(file string) (gitignore.GitIgnore, error) { 92 // reset the error slice 93 _test.errors = make([]gitignore.Error, 0) 94 95 // attempt to create the GitIgnore instance 96 _ignore := gitignore.NewWithCache(file, _test.cache, _test.error) 97 98 // if we encountered errors, and the first error has a zero position 99 // then it represents a file access error 100 // - extract the error and return it 101 // - remove it from the list of errors 102 var _err error 103 if len(_test.errors) > 0 { 104 if _test.errors[0].Position().Zero() { 105 _err = _test.errors[0].Underlying() 106 _test.errors = _test.errors[1:] 107 } 108 } 109 110 // return the GitIgnore instance 111 return _ignore, _err 112 } 113 114 // perform the gitignore test 115 withfile(t, _test, _GITIGNORE) 116 117 // repeat the tests while accumulating errors 118 _test.error = func(e gitignore.Error) bool { 119 _test.errors = append(_test.errors, e) 120 return true 121 } 122 withfile(t, _test, _GITIGNORE) 123 124 // create a temporary .gitignore 125 _file, _err := file(_GITIGNORE) 126 if _err != nil { 127 t.Fatalf("unable to create temporary .gitignore: %s", _err.Error()) 128 } 129 defer os.Remove(_file.Name()) 130 131 // attempt to load the .gitignore file 132 _ignore, _err := _test.instance(_file.Name()) 133 if _err != nil { 134 t.Fatalf("unable to open temporary .gitignore: %s", _err.Error()) 135 } 136 137 // remove the .gitignore and try again 138 os.Remove(_file.Name()) 139 140 // ensure the retrieved GitIgnore matches the stored instance 141 _new, _err := _test.instance(_file.Name()) 142 if _err != nil { 143 t.Fatalf( 144 "unexpected error retrieving cached .gitignore: %s", _err.Error(), 145 ) 146 } else if _new != _ignore { 147 t.Fatalf( 148 "gitignore.NewWithCache() mismatch; expected %v, got %v", 149 _ignore, _new, 150 ) 151 } 152 } // TestNewWithCache() 153 154 func TestNew(t *testing.T) { 155 // create a temporary .gitignore 156 _file, _err := file(_GITIGNORE) 157 if _err != nil { 158 t.Fatalf("unable to create temporary .gitignore: %s", _err.Error()) 159 } 160 defer os.Remove(_file.Name()) 161 162 // ensure we can run NewGitIgnore() 163 // - ensure we encounter the expected errors 164 _position := []gitignore.Position{} 165 _error := func(e gitignore.Error) bool { 166 _position = append(_position, e.Position()) 167 return true 168 } 169 170 _dir := filepath.Dir(_file.Name()) 171 _ignore := gitignore.New(_file, _dir, _error) 172 173 // ensure we have a non-nil GitIgnore instance 174 if _ignore == nil { 175 t.Error("expected non-nil GitIgnore instance; nil found") 176 } 177 178 // ensure the base of the ignore is the directory of the temporary file 179 if _ignore.Base() != _dir { 180 t.Errorf( 181 "gitignore.Base() mismatch; expected %q, got %q", 182 _dir, _ignore.Base(), 183 ) 184 } 185 186 // ensure we encountered the right number of errors 187 if len(_position) != _GITBADPATTERNS { 188 t.Errorf( 189 "parse error mismatch; expected %d errors, got %d", 190 _GITBADPATTERNS, len(_position), 191 ) 192 } else { 193 // ensure the error positions are correct 194 for _i := 0; _i < _GITBADPATTERNS; _i++ { 195 _got := _position[_i] 196 _expected := _GITBADPOSITION[_i] 197 198 // ensure the positions are correct 199 if !coincident(_got, _expected) { 200 t.Errorf("bad pattern position mismatch; expected %q, got %q", 201 pos(_expected), pos(_got), 202 ) 203 } 204 } 205 } 206 } // TestNew() 207 208 func withfile(t *testing.T, test *gitignoretest, content string) { 209 // create a temporary .gitignore 210 _file, _err := file(content) 211 if _err != nil { 212 t.Fatalf("unable to create temporary .gitignore: %s", _err.Error()) 213 } 214 defer os.Remove(_file.Name()) 215 216 // attempt to retrieve the GitIgnore instance 217 _ignore, _err := test.instance(_file.Name()) 218 if _err != nil { 219 t.Fatalf("unable to open temporary .gitignore: %s", _err.Error()) 220 } 221 222 // ensure we have a non-nil GitIgnore instance 223 if _ignore == nil { 224 t.Error("expected non-nil GitIgnore instance; nil found") 225 } 226 227 // ensure the base of the ignore is the directory of the temporary file 228 _dir := filepath.Dir(_file.Name()) 229 if _ignore.Base() != _dir { 230 t.Errorf( 231 "gitignore.Base() mismatch; expected %q, got %q", 232 _dir, _ignore.Base(), 233 ) 234 } 235 236 // ensure we encountered the right number of errors 237 // - only do this if we are configured to record bad patterns 238 if test.error != nil { 239 if len(test.errors) != _GITBADPATTERNS { 240 t.Errorf( 241 "parse error mismatch; expected %d errors, got %d", 242 _GITBADPATTERNS, len(test.errors), 243 ) 244 } else { 245 // ensure the error positions are correct 246 for _i := 0; _i < _GITBADPATTERNS; _i++ { 247 _got := test.errors[_i].Position() 248 _expected := _GITBADPOSITION[_i] 249 250 // augment the expected position with the test file name 251 _expected.File = _file.Name() 252 253 // ensure the positions are correct 254 if !coincident(_got, _expected) { 255 t.Errorf( 256 "bad pattern position mismatch; expected %q, got %q", 257 pos(_expected), pos(_got), 258 ) 259 } 260 } 261 } 262 } 263 264 // test NewFromFile() behaves as expected if the .gitgnore file does 265 // not exist 266 _err = os.Remove(_file.Name()) 267 if _err != nil { 268 t.Fatalf( 269 "unable to remove temporary .gitignore %s: %s", 270 _file.Name(), _err.Error(), 271 ) 272 } 273 _ignore, _err = test.instance(_file.Name()) 274 if _err == nil { 275 // if we are using a cache in this test, then no error is acceptable 276 // as long as a GitIgnore instance is retrieved 277 if test.cached { 278 if _ignore == nil { 279 t.Fatal("expected non-nil GitIgnore, nil found") 280 } 281 } else if test.error != nil { 282 t.Fatalf( 283 "expected error loading deleted file %s; none found", 284 _file.Name(), 285 ) 286 } 287 } else if !os.IsNotExist(_err) { 288 t.Fatalf( 289 "unexpected error attempting to load non-existant .gitignore: %s", 290 _err.Error(), 291 ) 292 } else if _ignore != nil { 293 t.Fatalf("expected nil GitIgnore, got %v", _ignore) 294 } 295 296 // test NewFromFile() behaves as expected if absolute path of the 297 // .gitignore cannot be determined 298 _map := map[string]string{gitignore.File: content} 299 _dir, _err = dir(_map) 300 if _err != nil { 301 t.Fatalf("unable to create temporary directory: %s", _err.Error()) 302 } 303 defer os.RemoveAll(_dir) 304 305 // change into the temporary directory 306 _cwd, _err := os.Getwd() 307 if _err != nil { 308 t.Fatalf("unable to retrieve working directory: %s", _err.Error()) 309 } 310 _err = os.Chdir(_dir) 311 if _err != nil { 312 t.Fatalf("unable to chdir into temporary directory: %s", _err.Error()) 313 } 314 defer os.Chdir(_cwd) 315 316 // remove permission from the temporary directory 317 _err = os.Chmod(_dir, 0) 318 if _err != nil { 319 t.Fatalf( 320 "unable to remove temporary directory permissions: %s: %s", 321 _dir, _err.Error(), 322 ) 323 } 324 325 // attempt to load the .gitignore using a relative path 326 _ignore, _err = test.instance(gitignore.File) 327 if test.error != nil && _err == nil { 328 _git := filepath.Join(_dir, gitignore.File) 329 t.Fatalf( 330 "%s: expected error for inaccessible .gitignore; none found", 331 _git, 332 ) 333 } else if _ignore != nil { 334 t.Fatalf("expected nil GitIgnore, got %v", _ignore) 335 } 336 } // withfile()