def test_function_list(mocker, mock_rust_notify: 'MockRustType'): mock_spawn_process = mocker.patch('watchfiles.run.spawn_context.Process', return_value=FakeProcess()) mock_kill = mocker.patch('watchfiles.run.os.kill') mock_rust_notify([{(1, '/path/to/foobar.py')}]) assert run_process('/x/y/z', target=['os.getcwd'], debounce=5, step=1) == 1 assert mock_spawn_process.call_count == 2 assert mock_kill.call_count == 2 # kill in loop + final kill
def test_alive_doesnt_terminate(mocker, mock_rust_notify: 'MockRustType'): mock_spawn_process = mocker.patch('watchfiles.run.spawn_context.Process', return_value=FakeProcess(exitcode=None)) mock_kill = mocker.patch('watchfiles.run.os.kill') mock_rust_notify([{(1, '/path/to/foobar.py')}]) assert run_process('/x/y/z', target=object(), debounce=5, step=1) == 1 assert mock_spawn_process.call_count == 2 assert mock_kill.call_count == 4 # 2 kills in loop (graceful and termination) + 2 final kills
def test_alive_terminates(mocker, mock_rust_notify: 'MockRustType', caplog): caplog.set_level('DEBUG', 'watchfiles') mock_spawn_process = mocker.patch('watchfiles.run.spawn_context.Process', return_value=FakeProcess()) mock_popen = mocker.patch('watchfiles.run.subprocess.Popen', return_value=FakePopen()) mock_kill = mocker.patch('watchfiles.run.os.kill') mock_rust_notify([{(1, '/path/to/foobar.py')}]) assert run_process('/x/y/z', target=os.getcwd, debounce=5, step=1) == 1 assert mock_spawn_process.call_count == 2 assert mock_popen.call_count == 0 assert mock_kill.call_count == 2 # kill in loop + final kill assert 'watchfiles.main DEBUG: running "<built-in function getcwd>" as function\n' in caplog.text
def test_command(mocker, mock_rust_notify: 'MockRustType', caplog): caplog.set_level('DEBUG', 'watchfiles') mock_spawn_process = mocker.patch('watchfiles.run.spawn_context.Process', return_value=FakeProcess()) mock_popen = mocker.patch('watchfiles.run.subprocess.Popen', return_value=FakePopen()) mock_kill = mocker.patch('watchfiles.run.os.kill') mock_rust_notify([{(1, '/path/to/foobar.py')}]) assert run_process('/x/y/z', target='echo foobar', debounce=5, step=1) == 1 assert mock_spawn_process.call_count == 0 assert mock_popen.call_count == 2 mock_popen.assert_called_with(['echo', 'foobar']) assert mock_kill.call_count == 2 # kill in loop + final kill assert 'watchfiles.main DEBUG: running "echo foobar" as command\n' in caplog.text
def test_sigint_timeout(mocker, mock_rust_notify: 'MockRustType', caplog): caplog.set_level('WARNING', 'watchfiles') mock_spawn_process = mocker.patch('watchfiles.run.spawn_context.Process', return_value=FakeProcessTimeout()) mock_kill = mocker.patch('watchfiles.run.os.kill') mock_rust_notify([{(1, '/path/to/foobar.py')}]) assert run_process('/x/y/z', target=object(), debounce=5, step=1, sigint_timeout='sigint_timeout') == 1 assert mock_spawn_process.call_count == 2 assert mock_kill.call_count == 2 assert "SIGINT timed out after 'sigint_timeout' seconds" in caplog.text
def test_dead_callback(mocker, mock_rust_notify: 'MockRustType'): mock_spawn_process = mocker.patch('watchfiles.run.spawn_context.Process', return_value=FakeProcess(is_alive=False)) mock_kill = mocker.patch('watchfiles.run.os.kill') mock_rust_notify([{(1, '/path/to/foobar.py')}, {(1, '/path/to/foobar.py')}]) c = mocker.MagicMock() assert run_process('/x/y/z', target=object(), callback=c, debounce=5, step=1) == 2 assert mock_spawn_process.call_count == 3 assert mock_kill.call_count == 0 assert c.call_count == 2 c.assert_called_with({(Change.added, '/path/to/foobar.py')})
def test_function_string_not_win(mocker, mock_rust_notify: 'MockRustType', caplog): caplog.set_level('DEBUG', 'watchfiles') mock_spawn_process = mocker.patch('watchfiles.run.spawn_context.Process', return_value=FakeProcess()) mocker.patch('watchfiles.run.os.kill') mock_rust_notify([{(1, '/path/to/foobar.py')}]) assert run_process('/x/y/z', target='os.getcwd', debounce=5, step=1) == 1 assert mock_spawn_process.call_count == 2 # get_tty_path returns None on windows tty_path = None if sys.platform == 'win32' else IsStr(regex='/dev/.+') mock_spawn_process.assert_called_with(target=run_function, args=('os.getcwd', tty_path, (), {}), kwargs={}) assert 'watchfiles.main DEBUG: running "os.getcwd" as function\n' in caplog.text
def test_command_with_args(mocker, mock_rust_notify: 'MockRustType', caplog): caplog.set_level('INFO', 'watchfiles') mock_spawn_process = mocker.patch('watchfiles.run.spawn_context.Process', return_value=FakeProcess()) mock_popen = mocker.patch('watchfiles.run.subprocess.Popen', return_value=FakePopen()) mock_kill = mocker.patch('watchfiles.run.os.kill') mock_rust_notify([{(1, '/path/to/foobar.py')}]) assert run_process('/x/y/z', target='echo foobar', args=(1, 2), target_type='command', debounce=5, step=1) == 1 assert mock_spawn_process.call_count == 0 assert mock_popen.call_count == 2 mock_popen.assert_called_with(['echo', 'foobar']) assert mock_kill.call_count == 2 # kill in loop + final kill assert 'watchfiles.main WARNING: ignoring args and kwargs for "command" target\n' in caplog.text