|
| 1 | +import os |
| 2 | +import types |
| 3 | +import unittest |
| 4 | + |
| 5 | +try: |
| 6 | + from unittest import mock |
| 7 | +except ImportError: |
| 8 | + # `Python 2` or lower than `Python 3.3` does not |
| 9 | + # have the `unittest.mock` module built-in |
| 10 | + import mock |
| 11 | +from pythonforandroid import util |
| 12 | + |
| 13 | + |
| 14 | +class TestUtil(unittest.TestCase): |
| 15 | + @mock.patch("pythonforandroid.util.makedirs") |
| 16 | + def test_ensure_dir(self, mock_makedirs): |
| 17 | + util.ensure_dir("fake_directory") |
| 18 | + mock_makedirs.assert_called_once_with("fake_directory") |
| 19 | + |
| 20 | + @mock.patch("shutil.rmtree") |
| 21 | + @mock.patch("pythonforandroid.util.mkdtemp") |
| 22 | + def test_temp_directory(self, mock_mkdtemp, mock_shutil_rmtree): |
| 23 | + mock_mkdtemp.return_value = "/temp/any_directory" |
| 24 | + with util.temp_directory(): |
| 25 | + mock_mkdtemp.assert_called_once() |
| 26 | + mock_shutil_rmtree.assert_called_once_with("/temp/any_directory") |
| 27 | + |
| 28 | + @mock.patch("pythonforandroid.util.chdir") |
| 29 | + def test_current_directory(self, moch_chdir): |
| 30 | + chdir_dir = "/temp/any_directory" |
| 31 | + # test chdir to existing directory |
| 32 | + with util.current_directory(chdir_dir): |
| 33 | + moch_chdir.assert_called_once_with("/temp/any_directory") |
| 34 | + moch_chdir.assert_has_calls( |
| 35 | + [ |
| 36 | + mock.call("/temp/any_directory"), |
| 37 | + mock.call(os.getcwd()), |
| 38 | + ] |
| 39 | + ) |
| 40 | + |
| 41 | + def test_current_directory_exception(self): |
| 42 | + # test chdir to non-existing directory, should raise error |
| 43 | + # for py3 the exception is FileNotFoundError and IOError for py2, to |
| 44 | + # avoid introduce conditions, we test with a more generic exception |
| 45 | + with self.assertRaises(OSError): |
| 46 | + with util.current_directory("/fake/directory"): |
| 47 | + # the line below will never be executed |
| 48 | + print("") |
| 49 | + |
| 50 | + @mock.patch("pythonforandroid.util.sh.which") |
| 51 | + def test_get_virtualenv_executable(self, mock_sh_which): |
| 52 | + # test that all calls to `sh.which` are performed, so we expect the |
| 53 | + # first two `sh.which` calls should be None and the last one should |
| 54 | + # return the expected virtualenv (the python3 one) |
| 55 | + expected_venv = os.path.join( |
| 56 | + os.path.expanduser("~"), ".local/bin/virtualenv" |
| 57 | + ) |
| 58 | + mock_sh_which.side_effect = [None, None, expected_venv] |
| 59 | + self.assertEqual(util.get_virtualenv_executable(), expected_venv) |
| 60 | + mock_sh_which.assert_has_calls( |
| 61 | + [ |
| 62 | + mock.call("virtualenv2"), |
| 63 | + mock.call("virtualenv-2.7"), |
| 64 | + mock.call("virtualenv"), |
| 65 | + ] |
| 66 | + ) |
| 67 | + self.assertEqual(mock_sh_which.call_count, 3) |
| 68 | + mock_sh_which.reset_mock() |
| 69 | + |
| 70 | + # Now test that we don't have virtualenv installed, so all calls to |
| 71 | + # `sh.which` should return None |
| 72 | + mock_sh_which.side_effect = [None, None, None] |
| 73 | + self.assertIsNone(util.get_virtualenv_executable()) |
| 74 | + self.assertEqual(mock_sh_which.call_count, 3) |
| 75 | + mock_sh_which.assert_has_calls( |
| 76 | + [ |
| 77 | + mock.call("virtualenv2"), |
| 78 | + mock.call("virtualenv-2.7"), |
| 79 | + mock.call("virtualenv"), |
| 80 | + ] |
| 81 | + ) |
| 82 | + |
| 83 | + def test_walk_valid_filens_sample(self): |
| 84 | + file_ens = util.walk_valid_filens( |
| 85 | + "/home/opacam/Devel/python-for-android/tests/", |
| 86 | + ["__pycache__"], |
| 87 | + ["*.pyc"], |
| 88 | + ) |
| 89 | + for i in os.walk("/home/opacam/Devel/python-for-android/tests/"): |
| 90 | + print(i) |
| 91 | + for i in file_ens: |
| 92 | + print(i) |
| 93 | + |
| 94 | + @mock.patch("pythonforandroid.util.walk") |
| 95 | + def test_walk_valid_filens(self, mock_walk): |
| 96 | + simulated_walk_result = [ |
| 97 | + ["/fake_dir", ["__pycache__", "Lib"], ["README", "setup.py"]], |
| 98 | + ["/fake_dir/Lib", ["ctypes"], ["abc.pyc", "abc.py"]], |
| 99 | + ["/fake_dir/Lib/ctypes", [], ["util.pyc", "util.py"]], |
| 100 | + ] |
| 101 | + # /fake_dir |
| 102 | + # |-- README |
| 103 | + # |-- setup.py |
| 104 | + # |-- __pycache__ |
| 105 | + # |-- |__ |
| 106 | + # |__Lib |
| 107 | + # |-- abc.pyc |
| 108 | + # |-- abc.py |
| 109 | + # |__ ctypes |
| 110 | + # |-- util.pyc |
| 111 | + # |-- util.py |
| 112 | + mock_walk.return_value = simulated_walk_result |
| 113 | + file_ens = util.walk_valid_filens( |
| 114 | + "/fake_dir", ["__pycache__"], ["*.py"] |
| 115 | + ) |
| 116 | + self.assertIsInstance(file_ens, types.GeneratorType) |
| 117 | + # given the simulated structure we expect: |
| 118 | + expected_result = { |
| 119 | + "/fake_dir/README", |
| 120 | + "/fake_dir/Lib/abc.pyc", |
| 121 | + "/fake_dir/Lib/ctypes/util.pyc", |
| 122 | + } |
| 123 | + result = set() |
| 124 | + for i in file_ens: |
| 125 | + result.add(i) |
| 126 | + |
| 127 | + self.assertEqual(result, expected_result) |
| 128 | + |
| 129 | + def test_util_exceptions(self): |
| 130 | + exc = util.BuildInterruptingException( |
| 131 | + "missing dependency xxx", instructions="pip install --user xxx" |
| 132 | + ) |
| 133 | + with self.assertRaises(SystemExit): |
| 134 | + util.handle_build_exception(exc) |
0 commit comments