source: test/test_path.py @ 1660:93ea351f922b

Last change on this file since 1660:93ea351f922b was 1660:93ea351f922b, checked in by Stefan Schwarzer <sschwarzer@…>, 4 years ago
Remove `unittest.main` calls Since we now use pytest as test runner and not a shell loop in the makefile, there's no longer a need for explicit `unittest.main` calls. ticket: 98
File size: 8.2 KB
Line 
1# encoding: utf-8
2# Copyright (C) 2003-2016, Stefan Schwarzer <sschwarzer@sschwarzer.net>
3# and ftputil contributors (see `doc/contributors.txt`)
4# See the file LICENSE for licensing terms.
5
6from __future__ import unicode_literals
7
8import ftplib
9import time
10import unittest
11
12import pytest
13
14import ftputil
15import ftputil.compat
16import ftputil.error
17import ftputil.tool
18
19from test import mock_ftplib
20from test import test_base
21
22
23class FailingFTPHost(ftputil.FTPHost):
24
25    def _dir(self, path):
26        raise ftputil.error.FTPOSError("simulate a failure, e. g. timeout")
27
28
29# Mock session, used for testing an inaccessible login directory
30class SessionWithInaccessibleLoginDirectory(mock_ftplib.MockSession):
31
32    def cwd(self, dir):
33        # Assume that `dir` is the inaccessible login directory.
34        raise ftplib.error_perm("can't change into this directory")
35
36
37class TestPath(unittest.TestCase):
38    """Test operations in `FTPHost.path`."""
39
40    def test_regular_isdir_isfile_islink(self):
41        """Test regular `FTPHost._Path.isdir/isfile/islink`."""
42        host = test_base.ftp_host_factory()
43        testdir = "/home/sschwarzer"
44        host.chdir(testdir)
45        # Test a path which isn't there.
46        assert not host.path.isdir("notthere")
47        assert not host.path.isfile("notthere")
48        assert not host.path.islink("notthere")
49        #  This checks additional code (see ticket #66).
50        assert not host.path.isdir("/notthere/notthere")
51        assert not host.path.isfile("/notthere/notthere")
52        assert not host.path.islink("/notthere/notthere")
53        # Test a directory.
54        assert host.path.isdir(testdir)
55        assert not host.path.isfile(testdir)
56        assert not host.path.islink(testdir)
57        # Test a file.
58        testfile = "/home/sschwarzer/index.html"
59        assert not host.path.isdir(testfile)
60        assert host.path.isfile(testfile)
61        assert not host.path.islink(testfile)
62        # Test a link. Since the link target of `osup` doesn't exist,
63        # neither `isdir` nor `isfile` return `True`.
64        testlink = "/home/sschwarzer/osup"
65        assert not host.path.isdir(testlink)
66        assert not host.path.isfile(testlink)
67        assert host.path.islink(testlink)
68
69    def test_workaround_for_spaces(self):
70        """Test whether the workaround for space-containing paths is used."""
71        host = test_base.ftp_host_factory()
72        testdir = "/home/sschwarzer"
73        host.chdir(testdir)
74        # Test a file name containing spaces.
75        testfile = "/home/dir with spaces/file with spaces"
76        assert not host.path.isdir(testfile)
77        assert host.path.isfile(testfile)
78        assert not host.path.islink(testfile)
79
80    def test_inaccessible_home_directory_and_whitespace_workaround(self):
81        "Test combination of inaccessible home directory + whitespace in path."
82        host = test_base.ftp_host_factory(
83               session_factory=SessionWithInaccessibleLoginDirectory)
84        with pytest.raises(ftputil.error.InaccessibleLoginDirError):
85            host._dir("/home dir")
86
87    def test_isdir_isfile_islink_with_exception(self):
88        """Test failing `FTPHost._Path.isdir/isfile/islink`."""
89        host = test_base.ftp_host_factory(ftp_host_class=FailingFTPHost)
90        testdir = "/home/sschwarzer"
91        host.chdir(testdir)
92        # Test if exceptions are propagated.
93        FTPOSError = ftputil.error.FTPOSError
94        with pytest.raises(FTPOSError):
95            host.path.isdir("index.html")
96        with pytest.raises(FTPOSError):
97            host.path.isfile("index.html")
98        with pytest.raises(FTPOSError):
99            host.path.islink("index.html")
100
101    def test_exists(self):
102        """Test `FTPHost.path.exists`."""
103        # Regular use of `exists`
104        host = test_base.ftp_host_factory()
105        testdir = "/home/sschwarzer"
106        host.chdir(testdir)
107        assert host.path.exists("index.html")
108        assert not host.path.exists("notthere")
109        # Test if exceptions are propagated.
110        host = test_base.ftp_host_factory(ftp_host_class=FailingFTPHost)
111        with pytest.raises(ftputil.error.FTPOSError):
112            host.path.exists("index.html")
113
114
115class TestAcceptEitherBytesOrUnicode(unittest.TestCase):
116
117    def setUp(self):
118        self.host = test_base.ftp_host_factory()
119
120    def _test_method_string_types(self, method, path):
121        expected_type = type(path)
122        assert isinstance(method(path), expected_type)
123
124    def test_methods_that_take_and_return_one_string(self):
125        """
126        Test whether the same string type as for the argument is returned.
127        """
128        bytes_type = ftputil.compat.bytes_type
129        unicode_type = ftputil.compat.unicode_type
130        method_names = ("abspath basename dirname join normcase normpath".
131                        split())
132        for method_name in method_names:
133            method = getattr(self.host.path, method_name)
134            self._test_method_string_types(method, "/")
135            self._test_method_string_types(method, ".")
136            self._test_method_string_types(method, b"/")
137            self._test_method_string_types(method, b".")
138
139    def test_methods_that_take_a_string_and_return_a_bool(self):
140        """Test whether the methods accept byte and unicode strings."""
141        host = self.host
142        as_bytes = ftputil.tool.as_bytes
143        host.chdir("/home/file_name_test")
144        # `isabs`
145        assert not host.path.isabs("ä")
146        assert not host.path.isabs(as_bytes("ä"))
147        # `exists`
148        assert host.path.exists("ä")
149        assert host.path.exists(as_bytes("ä"))
150        # `isdir`, `isfile`, `islink`
151        assert host.path.isdir("ä")
152        assert host.path.isdir(as_bytes("ä"))
153        assert host.path.isfile("ö")
154        assert host.path.isfile(as_bytes("ö"))
155        assert host.path.islink("ü")
156        assert host.path.islink(as_bytes("ü"))
157
158    def test_join(self):
159        """
160        Test whether `FTPHost.path.join` accepts only arguments of
161        the same string type and returns the same string type.
162        """
163        join = self.host.path.join
164        as_bytes = ftputil.tool.as_bytes
165        # Only unicode
166        parts = list("äöü")
167        result = join(*parts)
168        assert result == "ä/ö/ü"
169        #  Need explicit type check for Python 2
170        self.assertTrue(isinstance(result, ftputil.compat.unicode_type))
171        # Only bytes
172        parts = [as_bytes(s) for s in "äöü"]
173        result = join(*parts)
174        assert result == as_bytes("ä/ö/ü")
175        #  Need explicit type check for Python 2
176        assert isinstance(result, ftputil.compat.bytes_type)
177        # Mixture of unicode and bytes
178        parts = ["ä", as_bytes("ö")]
179        with pytest.raises(TypeError):
180            join(*parts)
181        parts = [as_bytes("ä"), as_bytes("ö"), "ü"]
182        with pytest.raises(TypeError):
183            join(*parts)
184
185    def test_getmtime(self):
186        """
187        Test whether `FTPHost.path.getmtime` accepts byte and unicode
188        paths.
189        """
190        host = self.host
191        as_bytes = ftputil.tool.as_bytes
192        host.chdir("/home/file_name_test")
193        # We don't care about the _exact_ time, so don't bother with
194        # timezone differences. Instead, do a simple sanity check.
195        day = 24 * 60 * 60  # seconds
196        expected_mtime = time.mktime((2000, 5, 29, 0, 0, 0, 0, 0, 0))
197        mtime_makes_sense = (lambda mtime: expected_mtime - day <= mtime <=
198                                           expected_mtime + day)
199        assert mtime_makes_sense(host.path.getmtime("ä"))
200        assert mtime_makes_sense(host.path.getmtime(as_bytes("ä")))
201
202    def test_getsize(self):
203        """
204        Test whether `FTPHost.path.getsize` accepts byte and unicode paths.
205        """
206        host = self.host
207        as_bytes = ftputil.tool.as_bytes
208        host.chdir("/home/file_name_test")
209        assert host.path.getsize("ä") == 512
210        assert host.path.getsize(as_bytes("ä")) == 512
211
212    def test_walk(self):
213        """Test whether `FTPHost.path.walk` accepts bytes and unicode paths."""
214        host = self.host
215        as_bytes = ftputil.tool.as_bytes
216        def noop(arg, top, names):
217            del names[:]
218        host.path.walk("ä", noop, None)
219        host.path.walk(as_bytes("ä"), noop, None)
Note: See TracBrowser for help on using the repository browser.