Cleanup check-psw, change api
[rarfile.git] / test / test_seek.py
blob5a89dfe6fff62549b76ce14145a16e95f5f45e89
1 """Test seeking on files.
2 """
4 import io
6 import pytest
8 import rarfile
10 ARC = "test/files/seektest.rar"
12 _WHENCE = 0
15 def do_seek(f, pos, lim, size=None):
16 global _WHENCE
17 ofs = pos * 4
18 fsize = lim * 4
20 if ofs < 0:
21 exp = 0
22 elif ofs > fsize:
23 exp = fsize
24 else:
25 exp = ofs
27 if size:
28 cur = f.tell()
29 if _WHENCE == 0:
30 f.seek(ofs, _WHENCE)
31 elif _WHENCE == 1:
32 f.seek(ofs - cur, _WHENCE)
33 else:
34 assert _WHENCE == 2
35 f.seek(ofs - size, _WHENCE)
36 _WHENCE = (_WHENCE + 1) % 3
37 else:
38 f.seek(ofs)
40 got = f.tell()
42 assert got == exp
43 ln = f.read(4)
44 if got == fsize and ln:
45 raise ValueError("unexpected read")
46 if not ln and got < fsize:
47 raise ValueError("unexpected read failure")
48 if ln:
49 spos = int(ln)
50 assert spos * 4 == got
53 def run_seek(rf, fn):
54 inf = rf.getinfo(fn)
55 cnt = int(inf.file_size / 4)
56 f = rf.open(fn)
58 with pytest.raises(ValueError):
59 f.seek(0, -1)
60 with pytest.raises(ValueError):
61 f.seek(0, 3)
63 do_seek(f, int(cnt / 2), cnt)
64 do_seek(f, 0, cnt)
66 for i in range(int(cnt / 2)):
67 do_seek(f, i * 2, cnt, inf.file_size)
69 for i in range(cnt):
70 do_seek(f, i * 2 - int(cnt / 2), cnt, inf.file_size)
72 for i in range(cnt + 10):
73 do_seek(f, cnt - i - 5, cnt, inf.file_size)
75 f.close()
78 def run_arc(arc, desc):
79 files = ["stest1.txt", "stest2.txt"]
80 rf = rarfile.RarFile(arc)
81 for fn in files:
82 run_seek(rf, fn)
85 def test_seek_filename():
86 run_arc(ARC, "fn")
89 def test_seek_bytesio():
90 # filelike: io.BytesIO, io.open()
91 with open(ARC, "rb") as f:
92 data = f.read()
93 run_arc(io.BytesIO(data), "io.BytesIO")
96 def test_seek_open():
97 # filelike: file()
98 with open(ARC, "rb") as f:
99 run_arc(f, "open")
102 def test_seek_ioopen():
103 # filelike: io.open()
104 with io.open(ARC, "rb") as f:
105 run_arc(f, "io.open")