Skip to content

Commit ff3aeb2

Browse files
committed
1 parent 03a0c92 commit ff3aeb2

1 file changed

Lines changed: 50 additions & 24 deletions

File tree

tests.py

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
from unittest.mock import patch, mock_open
22
from pathlib import Path
33
from tempfile import TemporaryDirectory
4+
from shutil import which
5+
from subprocess import run
6+
47

58
from gitignore_parser import parse_gitignore
69

7-
from unittest import TestCase, main, SkipTest
10+
from unittest import TestCase, main, SkipTest, skipUnless
811

912

1013
class Test(TestCase):
1114
def test_simple(self):
12-
matches = _parse_gitignore_string(
15+
matches = self._parse_gitignore_string(
1316
'__pycache__/\n'
1417
'*.py[cod]',
1518
fake_base_dir='/home/michael'
@@ -18,9 +21,10 @@ def test_simple(self):
1821
self.assertTrue(matches('/home/michael/main.pyc'))
1922
self.assertTrue(matches('/home/michael/dir/main.pyc'))
2023
self.assertTrue(matches('/home/michael/__pycache__'))
24+
self.assertTrue(matches('/home/michael/__pycache__/'))
2125

2226
def test_incomplete_filename(self):
23-
matches = _parse_gitignore_string('o.py', fake_base_dir='/home/michael')
27+
matches = self._parse_gitignore_string('o.py', fake_base_dir='/home/michael')
2428
self.assertTrue(matches('/home/michael/o.py'))
2529
self.assertFalse(matches('/home/michael/foo.py'))
2630
self.assertFalse(matches('/home/michael/o.pyc'))
@@ -29,7 +33,7 @@ def test_incomplete_filename(self):
2933
self.assertFalse(matches('/home/michael/dir/o.pyc'))
3034

3135
def test_wildcard(self):
32-
matches = _parse_gitignore_string(
36+
matches = self._parse_gitignore_string(
3337
'hello.*',
3438
fake_base_dir='/home/michael'
3539
)
@@ -41,7 +45,7 @@ def test_wildcard(self):
4145
self.assertFalse(matches('/home/michael/helloX'))
4246

4347
def test_anchored_wildcard(self):
44-
matches = _parse_gitignore_string(
48+
matches = self._parse_gitignore_string(
4549
'/hello.*',
4650
fake_base_dir='/home/michael'
4751
)
@@ -50,7 +54,7 @@ def test_anchored_wildcard(self):
5054
self.assertFalse(matches('/home/michael/a/hello.java'))
5155

5256
def test_trailingspaces(self):
53-
matches = _parse_gitignore_string(
57+
matches = self._parse_gitignore_string(
5458
'ignoretrailingspace \n'
5559
'notignoredspace\\ \n'
5660
'partiallyignoredspace\\ \n'
@@ -73,7 +77,7 @@ def test_trailingspaces(self):
7377
self.assertFalse(matches('/home/michael/notignoredmultiplespace'))
7478

7579
def test_comment(self):
76-
matches = _parse_gitignore_string(
80+
matches = self._parse_gitignore_string(
7781
'somematch\n'
7882
'#realcomment\n'
7983
'othermatch\n'
@@ -86,21 +90,21 @@ def test_comment(self):
8690
self.assertTrue(matches('/home/michael/#imnocomment'))
8791

8892
def test_ignore_directory(self):
89-
matches = _parse_gitignore_string('.venv/', fake_base_dir='/home/michael')
93+
matches = self.parse_gitignore_string('.venv/', fake_base_dir='/home/michael')
9094
self.assertTrue(matches('/home/michael/.venv'))
9195
self.assertTrue(matches('/home/michael/.venv/folder'))
9296
self.assertTrue(matches('/home/michael/.venv/file.txt'))
9397
self.assertFalse(matches('/home/michael/.venv_other_folder'))
9498
self.assertFalse(matches('/home/michael/.venv_no_folder.py'))
9599

96100
def test_ignore_directory_asterisk(self):
97-
matches = _parse_gitignore_string('.venv/*', fake_base_dir='/home/michael')
101+
matches = self._parse_gitignore_string('.venv/*', fake_base_dir='/home/michael')
98102
self.assertFalse(matches('/home/michael/.venv'))
99103
self.assertTrue(matches('/home/michael/.venv/folder'))
100104
self.assertTrue(matches('/home/michael/.venv/file.txt'))
101105

102106
def test_negation(self):
103-
matches = _parse_gitignore_string(
107+
matches = self._parse_gitignore_string(
104108
'''
105109
*.ignore
106110
!keep.ignore
@@ -112,20 +116,20 @@ def test_negation(self):
112116
self.assertTrue(matches('/home/michael/waste.ignore'))
113117

114118
def test_literal_exclamation_mark(self):
115-
matches = _parse_gitignore_string('\\!ignore_me!', fake_base_dir='/home/michael')
119+
matches = self._parse_gitignore_string('\\!ignore_me!', fake_base_dir='/home/michael')
116120
self.assertTrue(matches('/home/michael/!ignore_me!'))
117121
self.assertFalse(matches('/home/michael/ignore_me!'))
118122
self.assertFalse(matches('/home/michael/ignore_me'))
119123

120124
def test_double_asterisks(self):
121-
matches = _parse_gitignore_string('foo/**/Bar', fake_base_dir='/home/michael')
125+
matches = self._parse_gitignore_string('foo/**/Bar', fake_base_dir='/home/michael')
122126
self.assertTrue(matches('/home/michael/foo/hello/Bar'))
123127
self.assertTrue(matches('/home/michael/foo/world/Bar'))
124128
self.assertTrue(matches('/home/michael/foo/Bar'))
125129
self.assertFalse(matches('/home/michael/foo/BarBar'))
126130

127131
def test_double_asterisk_without_slashes_handled_like_single_asterisk(self):
128-
matches = _parse_gitignore_string('a/b**c/d', fake_base_dir='/home/michael')
132+
matches = self._parse_gitignore_string('a/b**c/d', fake_base_dir='/home/michael')
129133
self.assertTrue(matches('/home/michael/a/bc/d'))
130134
self.assertTrue(matches('/home/michael/a/bXc/d'))
131135
self.assertTrue(matches('/home/michael/a/bbc/d'))
@@ -136,15 +140,15 @@ def test_double_asterisk_without_slashes_handled_like_single_asterisk(self):
136140
self.assertFalse(matches('/home/michael/a/bb/XX/cc/d'))
137141

138142
def test_more_asterisks_handled_like_single_asterisk(self):
139-
matches = _parse_gitignore_string('***a/b', fake_base_dir='/home/michael')
143+
matches = self._parse_gitignore_string('***a/b', fake_base_dir='/home/michael')
140144
self.assertTrue(matches('/home/michael/XYZa/b'))
141145
self.assertFalse(matches('/home/michael/foo/a/b'))
142-
matches = _parse_gitignore_string('a/b***', fake_base_dir='/home/michael')
146+
matches = self._parse_gitignore_string('a/b***', fake_base_dir='/home/michael')
143147
self.assertTrue(matches('/home/michael/a/bXYZ'))
144148
self.assertFalse(matches('/home/michael/a/b/foo'))
145149

146150
def test_directory_only_negation(self):
147-
matches = _parse_gitignore_string('''
151+
matches = self._parse_gitignore_string('''
148152
data/**
149153
!data/**/
150154
!.gitkeep
@@ -160,18 +164,18 @@ def test_directory_only_negation(self):
160164
self.assertTrue(matches('/home/michael/data/02_processed/processed_file.csv'))
161165

162166
def test_single_asterisk(self):
163-
matches = _parse_gitignore_string('*', fake_base_dir='/home/michael')
167+
matches = self._parse_gitignore_string('*', fake_base_dir='/home/michael')
164168
self.assertTrue(matches('/home/michael/file.txt'))
165169
self.assertTrue(matches('/home/michael/directory'))
166170
self.assertTrue(matches('/home/michael/directory-trailing/'))
167171

168172
def test_supports_path_type_argument(self):
169-
matches = _parse_gitignore_string('file1\n!file2', fake_base_dir='/home/michael')
173+
matches = self._parse_gitignore_string('file1\n!file2', fake_base_dir='/home/michael')
170174
self.assertTrue(matches(Path('/home/michael/file1')))
171175
self.assertFalse(matches(Path('/home/michael/file2')))
172176

173177
def test_slash_in_range_does_not_match_dirs(self):
174-
matches = _parse_gitignore_string('abc[X-Z/]def', fake_base_dir='/home/michael')
178+
matches = self._parse_gitignore_string('abc[X-Z/]def', fake_base_dir='/home/michael')
175179
self.assertFalse(matches('/home/michael/abcdef'))
176180
self.assertTrue(matches('/home/michael/abcXdef'))
177181
self.assertTrue(matches('/home/michael/abcYdef'))
@@ -190,7 +194,7 @@ def test_symlink_to_another_directory(self):
190194
with TemporaryDirectory() as project_dir, TemporaryDirectory() as another_dir:
191195
project_dir = Path(project_dir).resolve()
192196
another_dir = Path(another_dir).resolve()
193-
matches = _parse_gitignore_string('link', fake_base_dir=project_dir)
197+
matches = self._parse_gitignore_string('link', fake_base_dir=project_dir)
194198

195199
# Create a symlink to another directory.
196200
link = project_dir / 'link'
@@ -207,10 +211,32 @@ def test_symlink_to_another_directory(self):
207211
# files.
208212
self.assertTrue(matches(link))
209213

210-
def _parse_gitignore_string(data: str, fake_base_dir: str = None):
211-
with patch('builtins.open', mock_open(read_data=data)):
212-
success = parse_gitignore(f'{fake_base_dir}/.gitignore', fake_base_dir)
213-
return success
214+
def _parse_gitignore_string(self, data: str, fake_base_dir: str|None = None):
215+
with patch('builtins.open', mock_open(read_data=data)):
216+
success = parse_gitignore(f'{fake_base_dir}/.gitignore', fake_base_dir)
217+
return success
218+
219+
@skipUnless(which("git"), "Git not installed")
220+
class TestAgainstGit(Test):
221+
"""Testcase running tests against `git check-ignore`.
222+
This is not to test if git is right, this is to validate that all
223+
tests from the Test class are valid according to git.
224+
"""
225+
def setUp(self):
226+
self.tmpdir = tempfile.TemporaryDirectory()
227+
run(["git", "init"], cwd=self.tmpdir.name)
228+
229+
def tearDown(self):
230+
self.tmpdir.cleanup()
231+
232+
def _parse_gitignore_string(self, data: str, fake_base_dir: Optional[str] = None):
233+
(Path(self.tmpdir.name) / ".gitignore").write_text(data, encoding="UTF-8")
234+
235+
def matcher(path):
236+
path = str(path).replace(fake_base_dir + "/", "")
237+
return run(["git", "check-ignore", path], cwd=self.tmpdir.name, check=False).returncode == 0
238+
239+
return matcher
214240

215241
if __name__ == '__main__':
216242
main()

0 commit comments

Comments
 (0)