github.com/muesli/go-gitignore@v0.0.0-20200714020803-ff91c85188b2/match_test.go (about)

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