tests: sync quoting style
[rarfile.git] / test / test_api.py
blob2528899cc042a54b28ff2938d86bcab0d9c48c2b
1 """API tests.
2 """
4 import io
5 import os
6 from pathlib import Path
8 import pytest
10 import rarfile
13 # test start
16 def test_not_rar():
17 with pytest.raises(rarfile.NotRarFile):
18 rarfile.RarFile("rarfile.py", "r")
19 with pytest.raises(rarfile.NotRarFile):
20 with open("rarfile.py", "rb") as f:
21 rarfile.RarFile(f, "r")
24 def test_bad_arc_mode_w():
25 with pytest.raises(NotImplementedError):
26 rarfile.RarFile("test/files/rar3-comment-plain.rar", "w")
29 def test_bad_arc_mode_rb():
30 with pytest.raises(NotImplementedError):
31 rarfile.RarFile("test/files/rar3-comment-plain.rar", "rb")
34 def test_bad_errs():
35 with pytest.raises(ValueError):
36 rarfile.RarFile("test/files/rar3-comment-plain.rar", "r", errors="foo")
39 def test_bad_open_mode_w():
40 rf = rarfile.RarFile("test/files/rar3-comment-plain.rar")
41 with pytest.raises(NotImplementedError):
42 rf.open("qwe", "w")
45 def test_bad_open_psw():
46 rf = rarfile.RarFile("test/files/rar3-comment-psw.rar")
47 with pytest.raises(rarfile.PasswordRequired):
48 rf.open("file1.txt")
51 def test_bad_filelike():
52 with pytest.raises(ValueError):
53 rarfile.is_rarfile(bytearray(10))
56 def test_open_psw_late_rar3():
57 rf = rarfile.RarFile("test/files/rar3-comment-psw.rar")
58 d1 = rf.open("file1.txt", "r", "password").read()
59 d2 = rf.open("file1.txt", "r", b"password").read()
60 assert d1 == d2
63 def test_open_psw_late_rar5():
64 rf = rarfile.RarFile("test/files/rar5-psw.rar")
65 rf.open("stest1.txt", "r", "password").read()
66 rf.open("stest1.txt", "r", b"password").read()
69 def test_open_pathlib_path():
70 rf = rarfile.RarFile("test/files/rar5-psw.rar")
71 rf.open(Path("stest1.txt"), "r", "password").read()
74 def test_read_psw_late_rar3():
75 rf = rarfile.RarFile("test/files/rar3-comment-psw.rar")
76 rf.read("file1.txt", "password")
77 rf.read("file1.txt", b"password")
80 def test_read_psw_late_rar5():
81 rf = rarfile.RarFile("test/files/rar5-psw.rar")
82 rf.read("stest1.txt", "password")
83 rf.read("stest1.txt", b"password")
86 def test_open_psw_late():
87 rf = rarfile.RarFile("test/files/rar5-psw.rar")
88 with pytest.raises(rarfile.BadRarFile):
89 rf.read("stest1.txt", "password222")
92 def test_create_from_pathlib_path():
93 # Make sure we can open both relative and absolute Paths
94 rarfile.RarFile(Path("test/files/rar5-psw.rar"))
95 rarfile.RarFile(Path("test/files/rar5-psw.rar").resolve())
98 def test_detection():
99 assert rarfile.is_rarfile("test/files/ctime4.rar.exp") is False
100 assert rarfile.is_rarfile("test/files/ctime4.rar") is True
101 assert rarfile.is_rarfile("test/files/rar5-crc.rar") is True
103 assert rarfile.is_rarfile(Path("test/files/rar5-crc.rar")) is True
106 def test_signature_error():
107 with pytest.raises(rarfile.NotRarFile):
108 rarfile.RarFile("test/files/ctime4.rar.exp")
111 def test_signature_error_mem():
112 data = io.BytesIO(b"x" * 40)
113 with pytest.raises(rarfile.NotRarFile):
114 rarfile.RarFile(data)
117 def test_with():
118 with rarfile.RarFile("test/files/rar5-crc.rar") as rf:
119 data = rf.read("stest1.txt")
120 with rf.open("stest1.txt") as f:
121 dst = io.BytesIO()
122 while True:
123 buf = f.read(7)
124 if not buf:
125 break
126 dst.write(buf)
127 assert dst.getvalue() == data
130 def test_readline():
131 def load_readline(rf, fn):
132 with rf.open(fn) as f:
133 tr = io.TextIOWrapper(io.BufferedReader(f))
134 res = []
135 while True:
136 ln = tr.readline()
137 if not ln:
138 break
139 res.append(ln)
140 return res
142 rf = rarfile.RarFile("test/files/seektest.rar")
143 v1 = load_readline(rf, "stest1.txt")
144 v2 = load_readline(rf, "stest2.txt")
145 assert len(v1) == 512
146 assert v1 == v2
149 def test_printdir(capsys):
150 rf = rarfile.RarFile("test/files/seektest.rar")
151 rf.printdir()
152 res = capsys.readouterr()
153 assert res.out == "stest1.txt\nstest2.txt\n"
156 def test_testrar():
157 rf = rarfile.RarFile("test/files/seektest.rar")
158 rf.testrar()
161 def test_iter():
162 rf = rarfile.RarFile("test/files/seektest.rar")
163 n1 = rf.namelist()
164 n2 = [m.filename for m in rf]
165 assert n1 == n2
168 def test_testrar_mem():
169 with open("test/files/seektest.rar", "rb") as f:
170 arc = f.read()
171 rf = rarfile.RarFile(io.BytesIO(arc))
172 rf.testrar()
175 def test_extract(tmp_path):
176 ex1 = tmp_path / "extract1"
177 ex2 = tmp_path / "extract2"
178 ex3 = tmp_path / "extract3"
179 os.makedirs(str(ex1))
180 os.makedirs(str(ex2))
181 os.makedirs(str(ex3))
182 rf = rarfile.RarFile("test/files/seektest.rar")
184 rf.extractall(str(ex1))
185 assert os.path.isfile(str(ex1 / "stest1.txt")) is True
186 assert os.path.isfile(str(ex1 / "stest2.txt")) is True
188 rf.extract("stest1.txt", str(ex2))
189 assert os.path.isfile(str(ex2 / "stest1.txt")) is True
190 assert os.path.isfile(str(ex2 / "stest2.txt")) is False
192 inf = rf.getinfo("stest2.txt")
193 rf.extract(inf, str(ex3))
194 assert os.path.isfile(str(ex3 / "stest1.txt")) is False
195 assert os.path.isfile(str(ex3 / "stest2.txt")) is True
197 rf.extractall(str(ex2), ["stest1.txt"])
198 assert os.path.isfile(str(ex2 / "stest1.txt")) is True
200 rf.extractall(str(ex3), [rf.getinfo("stest2.txt")])
201 assert os.path.isfile(str(ex3 / "stest2.txt")) is True
203 ex4 = tmp_path / "extract4"
204 os.makedirs(str(ex4))
205 rf.extractall(ex4)
206 assert os.path.isfile(str(ex4 / "stest1.txt")) is True
207 assert os.path.isfile(str(ex4 / "stest2.txt")) is True
210 def test_extract_mem(tmp_path):
211 ex1 = tmp_path / "extract11"
212 ex2 = tmp_path / "extract22"
213 ex3 = tmp_path / "extract33"
214 os.makedirs(str(ex1))
215 os.makedirs(str(ex2))
216 os.makedirs(str(ex3))
218 with open("test/files/seektest.rar", "rb") as f:
219 arc = f.read()
220 rf = rarfile.RarFile(io.BytesIO(arc))
222 rf.extractall(str(ex1))
223 assert os.path.isfile(str(ex1 / "stest1.txt")) is True
224 assert os.path.isfile(str(ex1 / "stest2.txt")) is True
226 rf.extract("stest1.txt", str(ex2))
227 assert os.path.isfile(str(ex2 / "stest1.txt")) is True
228 assert os.path.isfile(str(ex2 / "stest2.txt")) is False
230 inf = rf.getinfo("stest2.txt")
231 rf.extract(inf, str(ex3))
232 assert os.path.isfile(str(ex3 / "stest1.txt")) is False
233 assert os.path.isfile(str(ex3 / "stest2.txt")) is True
236 def get_rftype(h):
237 assert h.is_dir() == h.isdir()
238 return "".join([
239 h.is_file() and "F" or "-",
240 h.is_dir() and "D" or "-",
241 h.is_symlink() and "L" or "-",
245 def test_infocb():
246 infos = []
248 def info_cb(info):
249 infos.append((info.type, info.needs_password(), get_rftype(info), info._must_disable_hack()))
251 rf = rarfile.RarFile("test/files/seektest.rar", info_callback=info_cb)
252 assert infos == [
253 (rarfile.RAR_BLOCK_MAIN, False, "---", False),
254 (rarfile.RAR_BLOCK_FILE, False, "F--", False),
255 (rarfile.RAR_BLOCK_FILE, False, "F--", False),
256 (rarfile.RAR_BLOCK_ENDARC, False, "---", False)]
257 rf.close()
259 infos = []
260 rf = rarfile.RarFile("test/files/rar5-solid-qo.rar", info_callback=info_cb)
261 assert infos == [
262 (rarfile.RAR_BLOCK_MAIN, False, "---", True),
263 (rarfile.RAR_BLOCK_FILE, False, "F--", False),
264 (rarfile.RAR_BLOCK_FILE, False, "F--", True),
265 (rarfile.RAR_BLOCK_FILE, False, "F--", True),
266 (rarfile.RAR_BLOCK_FILE, False, "F--", True),
267 (rarfile.RAR_BLOCK_SUB, False, "---", False),
268 (rarfile.RAR_BLOCK_ENDARC, False, "---", False)]
269 rf.close()
272 # pylint: disable=singleton-comparison
273 def test_rarextfile():
274 with rarfile.RarFile("test/files/seektest.rar") as rf:
275 for fn in ("stest1.txt", "stest2.txt"):
276 with rf.open(fn) as f:
277 assert f.tell() == 0
278 assert f.writable() == False
279 assert f.seekable() == True
280 assert f.readable() == True
281 assert f.readall() == rf.read(fn)