github.com/LambdaTest/go-gitignore@v0.0.0-20230214141342-7fe15342e580/defn_test.go (about) 1 package gitignore_test 2 3 import ( 4 "path/filepath" 5 "strings" 6 7 "github.com/denormal/go-gitignore" 8 ) 9 10 type token struct { 11 Type gitignore.TokenType 12 Name string 13 Token string 14 Line int 15 Column int 16 NewLine int // token offset for newline end of line 17 CarriageReturn int // token offset for carriage return end of line 18 } // token{} 19 20 type match struct { 21 Path string // test path 22 Pattern string // matching pattern (if any) 23 Ignore bool // whether the path is ignored or included 24 Exclude bool // whether the match comes from the GIT_DIR/info/exclude file 25 } // match{} 26 27 func (m match) Local() string { 28 _path := m.Path 29 if m.IsDir() { 30 _path = strings.TrimSuffix(m.Path, "/") 31 } 32 33 // generate the local representation of the match path 34 return filepath.Join(strings.Split(_path, "/")...) 35 } // Local() 36 37 func (m match) IsDir() bool { 38 return strings.HasSuffix(m.Path, "/") 39 } // IsDir() 40 41 type position struct { 42 File string 43 Line int 44 Column int 45 Offset int 46 String string 47 } // position{} 48 49 // define the constants for the unit tests 50 const ( 51 // define the example .gitignore file contents 52 _GITIGNORE = ` 53 # example .gitignore 54 55 !*.go 56 57 *.o 58 *.a 59 60 /ignore/this/path/ 61 62 # the following line has trailing whitespace 63 /and/**/all/**/these/** 64 !/but/not/this\ 65 66 we support spaces 67 68 /**/this.is.not/a ** valid/pattern 69 /**/nor/is/***/this 70 /nor/is***this 71 northis** x 72 73 but \this\ is / valid\# 74 \ 75 76 so is this# 77 and this is #3 ok too 78 / // 79 ` 80 81 // define the example .gitignore file contents for the Match tests 82 // these tests have been taken from 83 // https://github.com/sdobz/backup/gitignore 84 // 85 // https://github.com/sdobz/backup/blob/master/gitignore/gitignore_test.go 86 _GITMATCH = ` 87 88 *.[oa] 89 *.html 90 *.min.js 91 92 !foo*.html 93 foo-excl.html 94 95 vmlinux* 96 97 \!important!.txt 98 99 log/*.log 100 !/log/foo.log 101 102 **/logdir/log 103 **/foodir/bar 104 exclude/** 105 106 !findthis* 107 108 **/hide/** 109 subdir/subdir2/ 110 111 /rootsubdir/ 112 113 dirpattern/ 114 115 README.md 116 117 # arch/foo/kernel/.gitignore 118 !arch/foo/kernel/vmlinux* 119 120 # htmldoc/.gitignore 121 !htmldoc/*.html 122 123 # git-sample-3/.gitignore 124 git-sample-3/* 125 !git-sample-3/foo 126 git-sample-3/foo/* 127 !git-sample-3/foo/bar 128 129 Documentation/*.pdf 130 Documentation/**/p*.pdf 131 ` 132 133 // define the number of good & bad patterns in the .gitignore above 134 _GITPATTERNS = 12 135 _GITBADPATTERNS = 4 136 137 // define the number of good & bad patterns in the match .gitignore above 138 _GITMATCHPATTERNS = 24 139 _GITBADMATCHPATTERNS = 0 140 141 // define the number of good and bad patterns returned when the 142 // gitignore.Parser error handler returns false upon receiving an error 143 _GITPATTERNSFALSE = 7 144 _GITBADPATTERNSFALSE = 1 145 146 // define the base path for a git repository 147 _GITBASE = "/my/git/repository" 148 149 // define the directory mask for any directories created during testing 150 _GITMASK = 0700 151 152 // define a .gitignore that will trigger lexer errors 153 _GITINVALID = "" + 154 "# the following two lines will trigger repeated lexer errors\n" + 155 "x\rx\rx\rx\n" + 156 "\rx\rx\rx\n" + 157 "!\rx\n" + 158 "/my/valid/pattern\n" + 159 "!\n" + 160 "** *\n" + 161 "/\r" 162 163 // define the number of invalid patterns and errors 164 _GITINVALIDERRORS = 10 165 _GITINVALIDERRORSFALSE = 1 166 _GITINVALIDPATTERNS = 1 167 _GITINVALIDPATTERNSFALSE = 0 168 169 // define the expected number of errors during repository matching 170 _GITREPOSITORYERRORS = 38 171 _GITREPOSITORYERRORSFALSE = 1 172 173 // define a .gitignore file the contains just whitespace & comments 174 _GITIGNORE_WHITESPACE = ` 175 # this is an empty .gitignore file 176 # - the following lines contains just whitespace 177 178 179 ` 180 ) 181 182 var ( 183 // define the positions of the bad patterns 184 _GITBADPOSITION = []gitignore.Position{ 185 gitignore.Position{File: "", Line: 17, Column: 19, Offset: 189}, 186 gitignore.Position{File: "", Line: 18, Column: 14, Offset: 219}, 187 gitignore.Position{File: "", Line: 19, Column: 8, Offset: 233}, 188 gitignore.Position{File: "", Line: 20, Column: 8, Offset: 248}, 189 } 190 191 // define the positions of the good patterns 192 _GITPOSITION = []gitignore.Position{ 193 gitignore.Position{File: "", Line: 4, Column: 1, Offset: 23}, 194 gitignore.Position{File: "", Line: 6, Column: 1, Offset: 30}, 195 gitignore.Position{File: "", Line: 7, Column: 1, Offset: 34}, 196 gitignore.Position{File: "", Line: 9, Column: 1, Offset: 39}, 197 gitignore.Position{File: "", Line: 12, Column: 1, Offset: 104}, 198 gitignore.Position{File: "", Line: 13, Column: 1, Offset: 132}, 199 gitignore.Position{File: "", Line: 15, Column: 1, Offset: 150}, 200 gitignore.Position{File: "", Line: 22, Column: 1, Offset: 256}, 201 gitignore.Position{File: "", Line: 23, Column: 1, Offset: 280}, 202 gitignore.Position{File: "", Line: 25, Column: 1, Offset: 283}, 203 gitignore.Position{File: "", Line: 26, Column: 1, Offset: 295}, 204 gitignore.Position{File: "", Line: 27, Column: 1, Offset: 317}, 205 } 206 207 // define the token stream for the _GITIGNORE .gitignore 208 _GITTOKENS = []token{ 209 // 1: 210 {gitignore.EOL, "EOL", "\n", 1, 1, 0, 0}, 211 // 2: # example .gitignore contents 212 {gitignore.COMMENT, "COMMENT", "# example .gitignore", 2, 1, 1, 2}, 213 {gitignore.EOL, "EOL", "\n", 2, 21, 21, 22}, 214 // 3: 215 {gitignore.EOL, "EOL", "\n", 3, 1, 22, 24}, 216 // 4: !*.go 217 {gitignore.NEGATION, "NEGATION", "!", 4, 1, 23, 26}, 218 {gitignore.PATTERN, "PATTERN", "*.go", 4, 2, 24, 27}, 219 {gitignore.EOL, "EOL", "\n", 4, 6, 28, 31}, 220 // 5: 221 {gitignore.EOL, "EOL", "\n", 5, 1, 29, 33}, 222 // 6: *.o 223 {gitignore.PATTERN, "PATTERN", "*.o", 6, 1, 30, 35}, 224 {gitignore.EOL, "EOL", "\n", 6, 4, 33, 38}, 225 // 7: *.a 226 {gitignore.PATTERN, "PATTERN", "*.a", 7, 1, 34, 40}, 227 {gitignore.EOL, "EOL", "\n", 7, 4, 37, 43}, 228 // 8: 229 {gitignore.EOL, "EOL", "\n", 8, 1, 38, 45}, 230 // 9: /ignore/this/path/ 231 {gitignore.SEPARATOR, "SEPARATOR", "/", 9, 1, 39, 47}, 232 {gitignore.PATTERN, "PATTERN", "ignore", 9, 2, 40, 48}, 233 {gitignore.SEPARATOR, "SEPARATOR", "/", 9, 8, 46, 54}, 234 {gitignore.PATTERN, "PATTERN", "this", 9, 9, 47, 55}, 235 {gitignore.SEPARATOR, "SEPARATOR", "/", 9, 13, 51, 59}, 236 {gitignore.PATTERN, "PATTERN", "path", 9, 14, 52, 60}, 237 {gitignore.SEPARATOR, "SEPARATOR", "/", 9, 18, 56, 64}, 238 {gitignore.EOL, "EOL", "\n", 9, 19, 57, 65}, 239 // 10: 240 {gitignore.EOL, "EOL", "\n", 10, 1, 58, 67}, 241 // 11: # the following line has trailing whitespace 242 {gitignore.COMMENT, "COMMENT", 243 "# the following line has trailing whitespace", 244 11, 1, 59, 69}, 245 {gitignore.EOL, "EOL", "\n", 11, 45, 103, 113}, 246 // 12: /and/**/all/**/these/** 247 {gitignore.SEPARATOR, "SEPARATOR", "/", 12, 1, 104, 115}, 248 {gitignore.PATTERN, "PATTERN", "and", 12, 2, 105, 116}, 249 {gitignore.SEPARATOR, "SEPARATOR", "/", 12, 5, 108, 119}, 250 {gitignore.ANY, "ANY", "**", 12, 6, 109, 120}, 251 {gitignore.SEPARATOR, "SEPARATOR", "/", 12, 8, 111, 122}, 252 {gitignore.PATTERN, "PATTERN", "all", 12, 9, 112, 123}, 253 {gitignore.SEPARATOR, "SEPARATOR", "/", 12, 12, 115, 126}, 254 {gitignore.ANY, "ANY", "**", 12, 13, 116, 127}, 255 {gitignore.SEPARATOR, "SEPARATOR", "/", 12, 15, 118, 129}, 256 {gitignore.PATTERN, "PATTERN", "these", 12, 16, 119, 130}, 257 {gitignore.SEPARATOR, "SEPARATOR", "/", 12, 21, 124, 135}, 258 {gitignore.ANY, "ANY", "**", 12, 22, 125, 136}, 259 {gitignore.WHITESPACE, "WHITESPACE", " \t ", 12, 24, 127, 138}, 260 {gitignore.EOL, "EOL", "\n", 12, 28, 131, 142}, 261 // 13: !/but/not/this\ 262 {gitignore.NEGATION, "NEGATION", "!", 13, 1, 132, 144}, 263 {gitignore.SEPARATOR, "SEPARATOR", "/", 13, 2, 133, 145}, 264 {gitignore.PATTERN, "PATTERN", "but", 13, 3, 134, 146}, 265 {gitignore.SEPARATOR, "SEPARATOR", "/", 13, 6, 137, 149}, 266 {gitignore.PATTERN, "PATTERN", "not", 13, 7, 138, 150}, 267 {gitignore.SEPARATOR, "SEPARATOR", "/", 13, 10, 141, 153}, 268 {gitignore.PATTERN, "PATTERN", "this\\ ", 13, 11, 142, 154}, 269 {gitignore.EOL, "EOL", "\n", 13, 17, 148, 160}, 270 // 14: 271 {gitignore.EOL, "EOL", "\n", 14, 1, 149, 162}, 272 // 15: we support spaces 273 {gitignore.PATTERN, "PATTERN", "we", 15, 1, 150, 164}, 274 {gitignore.WHITESPACE, "WHITESPACE", " ", 15, 3, 152, 166}, 275 {gitignore.PATTERN, "PATTERN", "support", 15, 4, 153, 167}, 276 {gitignore.WHITESPACE, "WHITESPACE", " ", 15, 11, 160, 174}, 277 {gitignore.PATTERN, "PATTERN", "spaces", 15, 14, 163, 177}, 278 {gitignore.EOL, "EOL", "\n", 15, 20, 169, 183}, 279 // 16: 280 {gitignore.EOL, "EOL", "\n", 16, 1, 170, 185}, 281 // 17: /**/this.is.not/a ** valid/pattern 282 {gitignore.SEPARATOR, "SEPARATOR", "/", 17, 1, 171, 187}, 283 {gitignore.ANY, "ANY", "**", 17, 2, 172, 188}, 284 {gitignore.SEPARATOR, "SEPARATOR", "/", 17, 4, 174, 190}, 285 {gitignore.PATTERN, "PATTERN", "this.is.not", 17, 5, 175, 191}, 286 {gitignore.SEPARATOR, "SEPARATOR", "/", 17, 16, 186, 202}, 287 {gitignore.PATTERN, "PATTERN", "a", 17, 17, 187, 203}, 288 {gitignore.WHITESPACE, "WHITESPACE", " ", 17, 18, 188, 204}, 289 {gitignore.ANY, "ANY", "**", 17, 19, 189, 205}, 290 {gitignore.WHITESPACE, "WHITESPACE", " ", 17, 21, 191, 207}, 291 {gitignore.PATTERN, "PATTERN", "valid", 17, 22, 192, 208}, 292 {gitignore.SEPARATOR, "SEPARATOR", "/", 17, 27, 197, 213}, 293 {gitignore.PATTERN, "PATTERN", "pattern", 17, 28, 198, 214}, 294 {gitignore.EOL, "EOL", "\n", 17, 35, 205, 221}, 295 // 18: /**/nor/is/***/this 296 {gitignore.SEPARATOR, "SEPARATOR", "/", 18, 1, 206, 223}, 297 {gitignore.ANY, "ANY", "**", 18, 2, 207, 224}, 298 {gitignore.SEPARATOR, "SEPARATOR", "/", 18, 4, 209, 226}, 299 {gitignore.PATTERN, "PATTERN", "nor", 18, 5, 210, 227}, 300 {gitignore.SEPARATOR, "SEPARATOR", "/", 18, 8, 213, 230}, 301 {gitignore.PATTERN, "PATTERN", "is", 18, 9, 214, 231}, 302 {gitignore.SEPARATOR, "SEPARATOR", "/", 18, 11, 216, 233}, 303 {gitignore.ANY, "ANY", "**", 18, 12, 217, 234}, 304 {gitignore.PATTERN, "PATTERN", "*", 18, 14, 219, 236}, 305 {gitignore.SEPARATOR, "SEPARATOR", "/", 18, 15, 220, 237}, 306 {gitignore.PATTERN, "PATTERN", "this", 18, 16, 221, 238}, 307 {gitignore.EOL, "EOL", "\n", 18, 20, 225, 242}, 308 // 19: /nor/is***this 309 {gitignore.SEPARATOR, "SEPARATOR", "/", 19, 1, 226, 244}, 310 {gitignore.PATTERN, "PATTERN", "nor", 19, 2, 227, 245}, 311 {gitignore.SEPARATOR, "SEPARATOR", "/", 19, 5, 230, 248}, 312 {gitignore.PATTERN, "PATTERN", "is", 19, 6, 231, 249}, 313 {gitignore.ANY, "ANY", "**", 19, 8, 233, 251}, 314 {gitignore.PATTERN, "PATTERN", "*this", 19, 10, 235, 253}, 315 {gitignore.EOL, "EOL", "\n", 19, 15, 240, 258}, 316 // 20: northis** x 317 {gitignore.PATTERN, "PATTERN", "northis", 20, 1, 241, 260}, 318 {gitignore.ANY, "ANY", "**", 20, 8, 248, 267}, 319 {gitignore.WHITESPACE, "WHITESPACE", " \t ", 20, 10, 250, 269}, 320 {gitignore.PATTERN, "PATTERN", "x", 20, 13, 253, 272}, 321 {gitignore.EOL, "EOL", "\n", 20, 14, 254, 273}, 322 // 21: 323 {gitignore.EOL, "EOL", "\n", 21, 1, 255, 275}, 324 // 22: but \this\ is / valid 325 {gitignore.PATTERN, "PATTERN", "but", 22, 1, 256, 277}, 326 {gitignore.WHITESPACE, "WHITESPACE", " ", 22, 4, 259, 280}, 327 {gitignore.PATTERN, "PATTERN", "\\this\\ is", 22, 5, 260, 281}, 328 {gitignore.WHITESPACE, "WHITESPACE", " ", 22, 14, 269, 290}, 329 {gitignore.SEPARATOR, "SEPARATOR", "/", 22, 15, 270, 291}, 330 {gitignore.WHITESPACE, "WHITESPACE", " ", 22, 16, 271, 292}, 331 {gitignore.PATTERN, "PATTERN", "valid\\#", 22, 17, 272, 293}, 332 {gitignore.EOL, "EOL", "\n", 22, 24, 279, 300}, 333 // 23: \ 334 {gitignore.PATTERN, "PATTERN", "\\", 23, 1, 280, 302}, 335 {gitignore.EOL, "EOL", "\n", 23, 2, 281, 303}, 336 // 24: 337 {gitignore.EOL, "EOL", "\n", 24, 1, 282, 305}, 338 // 25: so is this# 339 {gitignore.PATTERN, "PATTERN", "so", 25, 1, 283, 307}, 340 {gitignore.WHITESPACE, "WHITESPACE", " ", 25, 3, 285, 309}, 341 {gitignore.PATTERN, "PATTERN", "is", 25, 4, 286, 310}, 342 {gitignore.WHITESPACE, "WHITESPACE", " ", 25, 6, 288, 312}, 343 {gitignore.PATTERN, "PATTERN", "this#", 25, 7, 289, 313}, 344 {gitignore.EOL, "EOL", "\n", 25, 12, 294, 318}, 345 // 26: and this is #3 ok too 346 {gitignore.PATTERN, "PATTERN", "and", 26, 1, 295, 320}, 347 {gitignore.WHITESPACE, "WHITESPACE", " ", 26, 4, 298, 323}, 348 {gitignore.PATTERN, "PATTERN", "this", 26, 5, 299, 324}, 349 {gitignore.WHITESPACE, "WHITESPACE", " ", 26, 9, 303, 328}, 350 {gitignore.PATTERN, "PATTERN", "is", 26, 10, 304, 329}, 351 {gitignore.WHITESPACE, "WHITESPACE", " ", 26, 12, 306, 331}, 352 {gitignore.PATTERN, "PATTERN", "#3", 26, 13, 307, 332}, 353 {gitignore.WHITESPACE, "WHITESPACE", " ", 26, 15, 309, 334}, 354 {gitignore.PATTERN, "PATTERN", "ok", 26, 16, 310, 335}, 355 {gitignore.WHITESPACE, "WHITESPACE", " ", 26, 18, 312, 337}, 356 {gitignore.PATTERN, "PATTERN", "too", 26, 19, 313, 338}, 357 {gitignore.EOL, "EOL", "\n", 26, 22, 316, 341}, 358 // 27: / // 359 {gitignore.WHITESPACE, "WHITESPACE", " ", 27, 1, 317, 343}, 360 {gitignore.SEPARATOR, "SEPARATOR", "/", 27, 2, 318, 344}, 361 {gitignore.WHITESPACE, "WHITESPACE", " ", 27, 3, 319, 345}, 362 {gitignore.SEPARATOR, "SEPARATOR", "/", 27, 4, 320, 346}, 363 {gitignore.SEPARATOR, "SEPARATOR", "/", 27, 5, 321, 347}, 364 {gitignore.EOL, "EOL", "\n", 27, 6, 322, 348}, 365 366 {gitignore.EOF, "EOF", "", 28, 1, 323, 350}, 367 } 368 369 // define match tests and their expected results 370 _GITMATCHES = []match{ 371 {"!important!.txt", "\\!important!.txt", true, false}, 372 {"arch/", "", false, false}, 373 {"arch/foo/", "", false, false}, 374 {"arch/foo/kernel/", "", false, false}, 375 {"arch/foo/kernel/vmlinux.lds.S", "!arch/foo/kernel/vmlinux*", false, false}, 376 {"arch/foo/vmlinux.lds.S", "vmlinux*", true, false}, 377 {"bar/", "", false, false}, 378 {"bar/testfile", "", false, false}, 379 {"dirpattern", "", false, false}, 380 {"my/other/path/to/dirpattern", "", false, false}, 381 {"my/path/to/dirpattern/", "dirpattern/", true, false}, 382 {"my/path/to/dirpattern/some_file.txt", "", false, false}, 383 {"Documentation/", "", false, false}, 384 {"Documentation/foo-excl.html", "foo-excl.html", true, false}, 385 {"Documentation/foo.html", "!foo*.html", false, false}, 386 {"Documentation/gitignore.html", "*.html", true, false}, 387 {"Documentation/test.a.html", "*.html", true, false}, 388 {"exclude/", "exclude/**", true, false}, 389 {"exclude/dir1/", "exclude/**", true, false}, 390 {"exclude/dir1/dir2/", "exclude/**", true, false}, 391 {"exclude/dir1/dir2/dir3/", "exclude/**", true, false}, 392 {"exclude/dir1/dir2/dir3/testfile", "exclude/**", true, false}, 393 {"exclude/other_file.txt", "exclude/**", true, false}, 394 {"file.o", "*.[oa]", true, false}, 395 {"foo/exclude/some_file.txt", "", false, false}, 396 {"foo/exclude/other/file.txt", "", false, false}, 397 {"foodir/", "", false, false}, 398 {"foodir/bar/", "**/foodir/bar", true, false}, 399 {"foodir/bar/testfile", "", false, false}, 400 {"git-sample-3/", "", false, false}, 401 {"git-sample-3/foo/", "!git-sample-3/foo", false, false}, 402 {"git-sample-3/foo/bar/", "!git-sample-3/foo/bar", false, false}, 403 {"git-sample-3/foo/test/", "git-sample-3/foo/*", true, false}, 404 {"git-sample-3/test/", "git-sample-3/*", true, false}, 405 {"htmldoc/", "", false, false}, 406 {"htmldoc/docs.html", "!htmldoc/*.html", false, false}, 407 {"htmldoc/jslib.min.js", "*.min.js", true, false}, 408 {"lib.a", "*.[oa]", true, false}, 409 {"log/", "", false, false}, 410 {"log/foo.log", "!/log/foo.log", false, false}, 411 {"log/test.log", "log/*.log", true, false}, 412 {"rootsubdir/", "/rootsubdir/", true, false}, 413 {"rootsubdir/foo", "", false, false}, 414 {"src/", "", false, false}, 415 {"src/findthis.o", "!findthis*", false, false}, 416 {"src/internal.o", "*.[oa]", true, false}, 417 {"subdir/", "", false, false}, 418 {"subdir/hide/", "**/hide/**", true, false}, 419 {"subdir/hide/foo", "**/hide/**", true, false}, 420 {"subdir/logdir/", "", false, false}, 421 {"subdir/logdir/log/", "**/logdir/log", true, false}, 422 {"subdir/logdir/log/findthis.log", "!findthis*", false, false}, 423 {"subdir/logdir/log/foo.log", "", false, false}, 424 {"subdir/logdir/log/test.log", "", false, false}, 425 {"subdir/rootsubdir/", "", false, false}, 426 {"subdir/rootsubdir/foo", "", false, false}, 427 {"subdir/subdir2/", "subdir/subdir2/", true, false}, 428 {"subdir/subdir2/bar", "", false, false}, 429 {"README.md", "README.md", true, false}, 430 {"my-path/README.md", "README.md", true, false}, 431 {"my-path/also/README.md", "README.md", true, false}, 432 {"Documentation/git.pdf", "Documentation/*.pdf", true, false}, 433 {"Documentation/ppc/ppc.pdf", "Documentation/**/p*.pdf", true, false}, 434 {"tools/perf/Documentation/perf.pdf", "", false, false}, 435 } 436 437 // define the cache tests 438 _CACHETEST = map[string]gitignore.GitIgnore{ 439 "a": null(), 440 "a/b": null(), 441 "a/b/c": nil, 442 } 443 444 // define a set of cache keys known not to be in the cache tests above 445 _CACHEUNKNOWN = []string{ 446 "b", 447 "b/c", 448 } 449 450 // define the set of .gitignore files for a repository 451 _GITREPOSITORY = map[string]string{ 452 // define the top-level .gitignore file 453 "": ` 454 # ignore .bak files 455 *.bak 456 `, 457 // define subdirectory .gitignore files 458 "a": ` 459 # ignore .go files 460 *.go 461 462 # ignore every c directory 463 # - this should be the same as c/ 464 **/c/ 465 `, 466 "a/b": ` 467 # include .go files in this directory 468 !*.go 469 470 # include everything under e 471 !**/e/** 472 `, 473 "a/b/d": ` 474 # include c directories 475 !c/ 476 hidden/ 477 `, 478 } 479 480 // define the patterns for $GIT_DIR/info/exclude 481 _GITEXCLUDE = ` 482 # exclude every file using 'exclude' in its name 483 *exclude* 484 ` 485 486 // define repository match tests and their expected results 487 _REPOSITORYMATCHES = []match{ 488 // matching against the nested .gitignore files 489 {"include.go", "", false, false}, 490 {"ignore.go.bak", "*.bak", true, false}, 491 {"a/ignore.go", "*.go", true, false}, 492 {"a/ignore.go.bak", "*.bak", true, false}, 493 {"a/include.sh", "", false, false}, 494 {"a/c/ignore.go", "**/c/", true, false}, 495 {"a/c/ignore.go.bak", "**/c/", true, false}, 496 {"a/c/ignore.sh", "**/c/", true, false}, 497 {"a/c/", "**/c/", true, false}, 498 {"a/b/c/d/ignore.go", "**/c/", true, false}, 499 {"a/b/c/d/ignore.go.bak", "**/c/", true, false}, 500 {"a/b/c/d/ignore.sh", "**/c/", true, false}, 501 {"a/b/c/d/", "**/c/", true, false}, 502 {"a/b/c/", "**/c/", true, false}, 503 {"a/b/include.go", "!*.go", false, false}, 504 {"a/b/ignore.go.bak", "*.bak", true, false}, 505 {"a/b/include.sh", "", false, false}, 506 {"a/b/d/include.go", "!*.go", false, false}, 507 {"a/b/d/ignore.go.bak", "*.bak", true, false}, 508 {"a/b/d/include.sh", "", false, false}, 509 {"a/b/d/c/", "!c/", false, false}, 510 {"a/b/d/c/include.go", "!*.go", false, false}, 511 {"a/b/d/c/ignore.go.bak", "*.bak", true, false}, 512 {"a/b/d/c/include.sh", "", false, false}, 513 {"a/b/e/c/", "!**/e/**", false, false}, 514 {"a/b/e/c/include.go", "!**/e/**", false, false}, 515 {"a/b/e/c/include.go.bak", "!**/e/**", false, false}, 516 {"a/b/e/c/include.sh", "!**/e/**", false, false}, 517 518 // matching against GIT_DIR/info/exclude 519 {"exclude.me", "*exclude*", true, true}, 520 {"a/exclude.me", "*exclude*", true, true}, 521 {"a/b/exclude.me", "*exclude*", true, true}, 522 {"a/b/c/exclude.me", "**/c/", true, false}, 523 {"a/b/c/d/exclude.me", "**/c/", true, false}, 524 {"a/c/exclude.me", "**/c/", true, false}, 525 {"a/b/exclude.me", "*exclude*", true, true}, 526 {"a/b/d/exclude.me", "*exclude*", true, true}, 527 {"a/b/d/c/exclude.me", "*exclude*", true, true}, 528 {"a/b/e/c/exclude.me", "!**/e/**", false, false}, 529 } 530 531 // define the repository match tests and their expected results when the 532 // error handler returns false 533 _REPOSITORYMATCHESFALSE = []match{ 534 {"a/b/c_/d/e_/f/g/h/include.go~", "", false, false}, 535 } 536 537 // define the position tests 538 _POSITIONS = []position{ 539 {"", 0, 0, 0, "+0"}, 540 {"", 1, 0, 0, "1"}, 541 {"", 0, 1, 0, "+0"}, 542 {"", 0, 0, 1, "+1"}, 543 {"", 1, 2, 0, "1:2"}, 544 {"", 1, 0, 3, "1"}, 545 {"", 1, 2, 3, "1:2"}, 546 {"file", 0, 0, 0, "file: +0"}, 547 {"file", 1, 0, 0, "file: 1"}, 548 {"file", 0, 1, 0, "file: +0"}, 549 {"file", 0, 0, 1, "file: +1"}, 550 {"file", 1, 2, 0, "file: 1:2"}, 551 {"file", 1, 0, 3, "file: 1"}, 552 {"file", 1, 2, 3, "file: 1:2"}, 553 } 554 555 // define the token tests 556 // - we us the same position for all tokens, and ignore the 557 // token string (i.e. the sequence of runes that comprise this 558 // token), since we test the correctness of rune mappings to toknes 559 // in the above tests of example .gitignore files 560 _TOKENS = []token{ 561 {gitignore.ILLEGAL, "ILLEGAL", "", 1, 2, 3, 4}, 562 {gitignore.EOF, "EOF", "", 1, 2, 3, 4}, 563 {gitignore.EOL, "EOL", "", 1, 2, 3, 4}, 564 {gitignore.WHITESPACE, "WHITESPACE", "", 1, 2, 3, 4}, 565 {gitignore.COMMENT, "COMMENT", "", 1, 2, 3, 4}, 566 {gitignore.SEPARATOR, "SEPARATOR", "", 1, 2, 3, 4}, 567 {gitignore.NEGATION, "NEGATION", "", 1, 2, 3, 4}, 568 {gitignore.PATTERN, "PATTERN", "", 1, 2, 3, 4}, 569 {gitignore.ANY, "ANY", "", 1, 2, 3, 4}, 570 {gitignore.BAD, "BAD TOKEN", "", 1, 2, 3, 4}, 571 572 // invalid tokens 573 {-1, "BAD TOKEN", "", 1, 2, 3, 4}, 574 {12345, "BAD TOKEN", "", 1, 2, 3, 4}, 575 } 576 577 // define the beginning position for the parser & lexer 578 _BEGINNING = gitignore.Position{File: "", Line: 1, Column: 1, Offset: 0} 579 580 // define the tokens from the invalid .gitignore above 581 _TOKENSINVALID = []token{ 582 // 1: # the following two lines will trigger repeated lexer errors 583 {gitignore.COMMENT, 584 "COMMENT", 585 "# the following two lines will trigger repeated lexer errors", 586 1, 1, 0, 0}, 587 {gitignore.EOL, "EOL", "\n", 1, 61, 60, 60}, 588 // 2: x\rx\rx\rx 589 {gitignore.PATTERN, "PATTERN", "x", 2, 1, 61, 62}, 590 {gitignore.BAD, "BAD TOKEN", "\r", 2, 2, 62, 63}, 591 {gitignore.PATTERN, "PATTERN", "x", 2, 3, 63, 64}, 592 {gitignore.BAD, "BAD TOKEN", "\r", 2, 4, 64, 65}, 593 {gitignore.PATTERN, "PATTERN", "x", 2, 5, 65, 66}, 594 {gitignore.BAD, "BAD TOKEN", "\r", 2, 6, 66, 67}, 595 {gitignore.PATTERN, "PATTERN", "x", 2, 7, 67, 68}, 596 {gitignore.EOL, "EOL", "\n", 2, 8, 68, 69}, 597 // 3: x\rx\rx\rx 598 {gitignore.BAD, "BAD TOKEN", "\r", 3, 1, 69, 71}, 599 {gitignore.PATTERN, "PATTERN", "x", 3, 2, 70, 72}, 600 {gitignore.BAD, "BAD TOKEN", "\r", 3, 3, 71, 73}, 601 {gitignore.PATTERN, "PATTERN", "x", 3, 4, 72, 74}, 602 {gitignore.BAD, "BAD TOKEN", "\r", 3, 5, 73, 75}, 603 {gitignore.PATTERN, "PATTERN", "x", 3, 6, 74, 76}, 604 {gitignore.EOL, "EOL", "\n", 3, 7, 75, 77}, 605 // 4: !\rx 606 {gitignore.NEGATION, "NEGATION", "!", 4, 1, 76, 79}, 607 {gitignore.BAD, "BAD TOKEN", "\r", 4, 2, 77, 80}, 608 {gitignore.PATTERN, "PATTERN", "x", 4, 3, 78, 81}, 609 {gitignore.EOL, "EOL", "\n", 4, 4, 79, 82}, 610 // 5: /my/valid/pattern 611 {gitignore.SEPARATOR, "SEPARATOR", "/", 5, 1, 80, 84}, 612 {gitignore.PATTERN, "PATTERN", "my", 5, 2, 81, 85}, 613 {gitignore.SEPARATOR, "SEPARATOR", "/", 5, 4, 83, 87}, 614 {gitignore.PATTERN, "PATTERN", "valid", 5, 5, 84, 88}, 615 {gitignore.SEPARATOR, "SEPARATOR", "/", 5, 10, 89, 93}, 616 {gitignore.PATTERN, "PATTERN", "pattern", 5, 11, 90, 94}, 617 {gitignore.EOL, "EOL", "\n", 5, 18, 97, 101}, 618 // 6: ! 619 {gitignore.NEGATION, "NEGATION", "!", 6, 1, 98, 103}, 620 {gitignore.EOL, "EOL", "\n", 6, 2, 99, 104}, 621 // 7: ** * 622 {gitignore.ANY, "ANY", "**", 7, 1, 100, 106}, 623 {gitignore.WHITESPACE, "WHITESPACE", " ", 7, 3, 102, 108}, 624 {gitignore.PATTERN, "PATTERN", "*", 7, 4, 103, 109}, 625 {gitignore.EOL, "EOL", "\n", 7, 5, 104, 110}, 626 // 8: /\r 627 {gitignore.SEPARATOR, "SEPARATOR", "/", 8, 1, 105, 112}, 628 {gitignore.BAD, "BAD TOKEN", "\r", 8, 2, 106, 113}, 629 630 {gitignore.EOF, "EOF", "", 8, 3, 107, 114}, 631 } 632 633 // define the patterns & errors expected during invalid content parsing 634 _GITINVALIDPATTERN = []string{"/my/valid/pattern"} 635 _GITINVALIDERROR = []error{ 636 gitignore.CarriageReturnError, 637 gitignore.CarriageReturnError, 638 gitignore.CarriageReturnError, 639 gitignore.CarriageReturnError, 640 gitignore.CarriageReturnError, 641 gitignore.CarriageReturnError, 642 gitignore.CarriageReturnError, 643 gitignore.InvalidPatternError, 644 gitignore.InvalidPatternError, 645 gitignore.CarriageReturnError, 646 } 647 )