1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
import re
import sys
from pathlib import Path
from typing import TYPE_CHECKING
import pytest
from dirty_equals import IsTuple
from watchfiles import Change, DefaultFilter, PythonFilter, watch
if TYPE_CHECKING:
from conftest import MockRustType
def test_ignore_file(mock_rust_notify: 'MockRustType'):
mock = mock_rust_notify([{(1, 'spam.pyc'), (1, 'spam.swp'), (1, 'foo.txt')}])
assert next(watch('.')) == {(Change.added, 'foo.txt')}
assert mock.watch_count == 1
def test_ignore_dir(mock_rust_notify: 'MockRustType'):
mock_rust_notify([{(1, '.git'), (1, str(Path('.git') / 'spam')), (1, 'foo.txt')}])
assert next(watch('.')) == {(Change.added, 'foo.txt')}
def test_python(mock_rust_notify: 'MockRustType'):
mock_rust_notify([{(2, 'spam.txt'), (2, 'spam.md'), (2, 'foo.py')}])
assert next(watch('.', watch_filter=PythonFilter())) == {(Change.modified, 'foo.py')}
def test_python_extensions(mock_rust_notify: 'MockRustType'):
mock_rust_notify([{(1, 'spam.txt'), (1, 'spam.md'), (1, 'foo.py')}])
f = PythonFilter(extra_extensions=('.md',))
assert next(watch('.', watch_filter=f)) == {(Change.added, 'foo.py'), (Change.added, 'spam.md')}
def test_web_filter(mock_rust_notify: 'MockRustType'):
# test case from docs
class WebFilter(DefaultFilter):
allowed_extensions = '.html', '.css', '.js'
def __call__(self, change: Change, path: str) -> bool:
return super().__call__(change, path) and path.endswith(self.allowed_extensions)
mock_rust_notify([{(1, 'foo.txt'), (2, 'bar.html'), (3, 'spam.xlsx'), (1, '.other.js')}])
assert next(watch('.', watch_filter=WebFilter())) == {(Change.modified, 'bar.html'), (Change.added, '.other.js')}
def test_simple_function(mock_rust_notify: 'MockRustType'):
mock_rust_notify([{(1, 'added.txt'), (2, 'mod.txt'), (3, 'del.txt')}])
def only_added(change: Change, path: str) -> bool:
return change == Change.added
assert next(watch('.', watch_filter=only_added)) == {(Change.added, 'added.txt')}
@pytest.mark.parametrize(
'path,expected',
[
('foo.txt', True),
('foo.swp', False),
('foo.swx', False),
('foo.swx.more', True),
(Path('x/y/z/foo.txt'), True),
(Path.home() / 'ignore' / 'foo.txt', False),
(Path.home() / 'ignore', False),
(Path.home() / '.git' / 'foo.txt', False),
(Path.home() / 'foo' / 'foo.txt', True),
(Path('.git') / 'foo.txt', False),
],
)
def test_default_filter(path, expected):
f = DefaultFilter(ignore_paths=[Path.home() / 'ignore'])
assert f(Change.added, str(path)) == expected
@pytest.mark.skipif(sys.platform == 'win32', reason='paths are different on windows')
def test_customising_filters():
f = DefaultFilter(ignore_dirs=['apple', 'banana'], ignore_entity_patterns=[r'\.cat$'], ignore_paths=[Path('/a/b')])
assert f.ignore_dirs == ['apple', 'banana']
assert f._ignore_dirs == {'apple', 'banana'}
assert f.ignore_entity_patterns == [r'\.cat$']
assert f._ignore_entity_regexes == (re.compile(r'\.cat$'),)
assert f.ignore_paths == [Path('/a/b')]
assert f._ignore_paths == ('/a/b',)
# unchanged
assert DefaultFilter.ignore_dirs == IsTuple('__pycache__', length=11)
def test_repr():
f = DefaultFilter(ignore_dirs=['apple', 'banana'])
assert repr(f).startswith('DefaultFilter(_ignore_dirs={')
|