Skip to content

Commit eb59e5d

Browse files
committed
Add tests checking WrapReadOnly works with fs.copy, fs.mirror and fs.move
1 parent 99b0cca commit eb59e5d

File tree

2 files changed

+68
-8
lines changed

2 files changed

+68
-8
lines changed

fs/wrap.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ class WrapCachedDir(WrapFS[_F], typing.Generic[_F]):
100100
#
101101
# A possible solution would be to replaced the cached with a
102102
# Dict[Text, Dict[Text, Dict[Text, Info]]]
103-
# ^ ^ ^ ^~~ the actual info object
104-
# | | |~~ the path of the directory entry
105-
# | |~~ the namespace of the info
106-
# |~~ the cached directory entry
103+
# ^ ^ ^ ^-- the actual info object
104+
# | | \-- the path of the directory entry
105+
# | \-- the namespace of the info
106+
# \-- the cached directory entry
107107
#
108108
# Furthermore, `listdir` and `filterdir` calls should be cached as well,
109109
# since they can be written as wrappers of `scandir`.

tests/test_wrap.py

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,24 @@
22

33
import operator
44
import unittest
5+
56
try:
67
from unittest import mock
78
except ImportError:
89
import mock
910

1011
import six
1112

13+
import fs.copy
14+
import fs.mirror
15+
import fs.move
1216
import fs.wrap
1317
import fs.errors
1418
from fs import open_fs
1519
from fs.info import Info
1620

1721

1822
class TestWrapReadOnly(unittest.TestCase):
19-
2023
def setUp(self):
2124
self.fs = open_fs("mem://")
2225
self.ro = fs.wrap.read_only(self.fs)
@@ -95,8 +98,65 @@ def test_open_r(self):
9598
self.assertEqual(read_file.read(), b"read me")
9699

97100

98-
class TestWrapCachedDir(unittest.TestCase):
101+
class TestWrapReadOnlySyspath(unittest.TestCase):
102+
# If the wrapped fs has a syspath, there is a chance that somewhere
103+
# in fs.copy or fs.mirror we try to use it to our advantage, but
104+
# we want to make sure these implementations don't circumvent the
105+
# wrapper.
106+
107+
def setUp(self):
108+
self.fs = open_fs("temp://")
109+
self.ro = fs.wrap.read_only(self.fs)
110+
self.src = open_fs("temp://")
111+
self.src.touch("foo")
112+
self.src.makedir("bar")
113+
114+
def tearDown(self):
115+
self.fs.close()
116+
self.src.close()
117+
118+
def assertReadOnly(self, func, *args, **kwargs):
119+
self.assertRaises(fs.errors.ResourceReadOnly, func, *args, **kwargs)
99120

121+
def test_copy_fs(self):
122+
self.assertReadOnly(fs.copy.copy_fs, self.src, self.ro)
123+
124+
def test_copy_fs_if_newer(self):
125+
self.assertReadOnly(fs.copy.copy_fs_if_newer, self.src, self.ro)
126+
127+
def test_copy_file(self):
128+
self.assertReadOnly(fs.copy.copy_file, self.src, "foo", self.ro, "foo")
129+
130+
def test_copy_file_if_newer(self):
131+
self.assertReadOnly(fs.copy.copy_file_if_newer, self.src, "foo", self.ro, "foo")
132+
133+
def test_copy_structure(self):
134+
self.assertReadOnly(fs.copy.copy_structure, self.src, self.ro)
135+
136+
def test_mirror(self):
137+
self.assertReadOnly(fs.mirror.mirror, self.src, self.ro)
138+
fs.mirror.mirror(self.src, self.fs)
139+
self.fs.touch("baz")
140+
self.assertReadOnly(fs.mirror.mirror, self.src, self.ro)
141+
142+
def test_move_fs(self):
143+
self.assertReadOnly(fs.move.move_fs, self.src, self.ro)
144+
self.src.removetree("/")
145+
self.fs.touch("foo")
146+
self.assertReadOnly(fs.move.move_fs, self.ro, self.src)
147+
148+
def test_move_file(self):
149+
self.assertReadOnly(fs.move.move_file, self.src, "foo", self.ro, "foo")
150+
self.fs.touch("baz")
151+
self.assertReadOnly(fs.move.move_file, self.ro, "baz", self.src, "foo")
152+
153+
def test_move_dir(self):
154+
self.assertReadOnly(fs.move.move_file, self.src, "bar", self.ro, "bar")
155+
self.fs.makedir("baz")
156+
self.assertReadOnly(fs.move.move_dir, self.ro, "baz", self.src, "baz")
157+
158+
159+
class TestWrapCachedDir(unittest.TestCase):
100160
def setUp(self):
101161
self.fs = open_fs("mem://")
102162
self.fs.makedirs("foo/bar/baz")
@@ -126,7 +186,7 @@ def test_isdir(self):
126186
with mock.patch.object(self.fs, "scandir", wraps=self.fs.scandir) as scandir:
127187
self.assertTrue(self.cached.isdir("foo"))
128188
self.assertFalse(self.cached.isdir("egg")) # is file
129-
self.assertFalse(self.cached.isdir("spam")) # doesn't exist
189+
self.assertFalse(self.cached.isdir("spam")) # doesn't exist
130190
scandir.assert_called()
131191
with mock.patch.object(self.fs, "scandir", wraps=self.fs.scandir) as scandir:
132192
self.assertTrue(self.cached.isdir("foo"))
@@ -138,7 +198,7 @@ def test_isfile(self):
138198
with mock.patch.object(self.fs, "scandir", wraps=self.fs.scandir) as scandir:
139199
self.assertTrue(self.cached.isfile("egg"))
140200
self.assertFalse(self.cached.isfile("foo")) # is dir
141-
self.assertFalse(self.cached.isfile("spam")) # doesn't exist
201+
self.assertFalse(self.cached.isfile("spam")) # doesn't exist
142202
scandir.assert_called()
143203
with mock.patch.object(self.fs, "scandir", wraps=self.fs.scandir) as scandir:
144204
self.assertTrue(self.cached.isfile("egg"))

0 commit comments

Comments
 (0)