1
0
mirror of https://github.com/arsenetar/send2trash.git synced 2025-08-30 04:29:42 +00:00

Compare commits

...

3 Commits

Author SHA1 Message Date
10c7693d11
Minor fixes to tests 2021-03-17 21:51:51 -05:00
356509120b
Add some checks to catch test failure
Really just checking that the setup is able to create test files so it
is known they were there then removed.
Windows tests really need verification of
recycle, which is not present.
2021-03-17 20:52:16 -05:00
f9fcdb8d8c
Fix legacy windows platform for multibyte unicode
- Add handling to create correctly sized buffer even with multibyte
characters as len() in python does not line up with what
create_unicode_buffer() needs for length.
- Add test for single and multiple files
2021-03-10 21:41:30 -06:00
4 changed files with 45 additions and 5 deletions

View File

@ -77,8 +77,6 @@ def send2trash(paths):
paths = [op.abspath(path) if not op.isabs(path) else path for path in paths] paths = [op.abspath(path) if not op.isabs(path) else path for path in paths]
# get short path to handle path length issues # get short path to handle path length issues
paths = [get_short_path_name(path) for path in paths] paths = [get_short_path_name(path) for path in paths]
# convert to a single string of null terminated paths
paths = "\0".join(paths)
fileop = SHFILEOPSTRUCTW() fileop = SHFILEOPSTRUCTW()
fileop.hwnd = 0 fileop.hwnd = 0
fileop.wFunc = FO_DELETE fileop.wFunc = FO_DELETE
@ -93,7 +91,15 @@ def send2trash(paths):
# NOTE: based on how python allocates memory for these types they should # NOTE: based on how python allocates memory for these types they should
# always be zero, if this is ever not true we can go back to explicitly # always be zero, if this is ever not true we can go back to explicitly
# setting the last two characters to null using buffer[index] = '\0'. # setting the last two characters to null using buffer[index] = '\0'.
buffer = create_unicode_buffer(paths, len(paths) + 2) # Additional note on another issue here, unicode_buffer expects length in
# bytes essentially, so having multi-byte characters causes issues if just
# passing pythons string length. Instead of dealing with this difference we
# just create a buffer then a new one with an extra null. Since the non-length
# specified version apparently stops after the first null, join with a space first.
buffer = create_unicode_buffer(" ".join(paths))
# convert to a single string of null terminated paths
path_string = "\0".join(paths)
buffer = create_unicode_buffer(path_string, len(buffer) + 1)
fileop.pFrom = LPCWSTR(addressof(buffer)) fileop.pFrom = LPCWSTR(addressof(buffer))
fileop.pTo = None fileop.pTo = None
fileop.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT fileop.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT

View File

@ -32,6 +32,7 @@ def testfile():
dir=op.expanduser("~"), prefix="send2trash_test", delete=False dir=op.expanduser("~"), prefix="send2trash_test", delete=False
) )
file.close() file.close()
assert op.exists(file.name) is True
yield file yield file
# Cleanup trash files on supported platforms # Cleanup trash files on supported platforms
if sys.platform != "win32": if sys.platform != "win32":
@ -57,6 +58,7 @@ def testfiles():
) )
) )
[file.close() for file in files] [file.close() for file in files]
assert all([op.exists(file.name) for file in files]) is True
yield files yield files
filenames = [op.basename(file.name) for file in files] filenames = [op.basename(file.name) for file in files]
[os.remove(op.join(HOMETRASH, "files", filename)) for filename in filenames] [os.remove(op.join(HOMETRASH, "files", filename)) for filename in filenames]
@ -93,6 +95,7 @@ def testUnicodefile():
name = u"send2trash_tést1" name = u"send2trash_tést1"
file = op.join(op.expanduser(b"~"), name.encode("utf-8")) file = op.join(op.expanduser(b"~"), name.encode("utf-8"))
touch(file) touch(file)
assert op.exists(file) is True
yield file yield file
# Cleanup trash files on supported platforms # Cleanup trash files on supported platforms
if sys.platform != "win32": if sys.platform != "win32":
@ -158,6 +161,7 @@ def testExtVol():
fileName = "test.txt" fileName = "test.txt"
filePath = op.join(volume.trashTopdir, fileName) filePath = op.join(volume.trashTopdir, fileName)
touch(filePath) touch(filePath)
assert op.exists(filePath) is True
yield volume, fileName, filePath yield volume, fileName, filePath
volume.cleanup() volume.cleanup()

View File

@ -26,6 +26,7 @@ def _create_tree(path):
@pytest.fixture @pytest.fixture
def testdir(tmp_path): def testdir(tmp_path):
dirname = "\\\\?\\" + str(tmp_path) dirname = "\\\\?\\" + str(tmp_path)
assert op.exists(dirname) is True
yield dirname yield dirname
shutil.rmtree(dirname, ignore_errors=True) shutil.rmtree(dirname, ignore_errors=True)
@ -34,6 +35,7 @@ def testdir(tmp_path):
def testfile(testdir): def testfile(testdir):
file = op.join(testdir, "testfile.txt") file = op.join(testdir, "testfile.txt")
_create_tree(file) _create_tree(file)
assert op.exists(file) is True
yield file yield file
# Note dir will cleanup the file # Note dir will cleanup the file
@ -42,6 +44,7 @@ def testfile(testdir):
def testfiles(testdir): def testfiles(testdir):
files = [op.join(testdir, "testfile{}.txt".format(index)) for index in range(10)] files = [op.join(testdir, "testfile{}.txt".format(index)) for index in range(10)]
[_create_tree(file) for file in files] [_create_tree(file) for file in files]
assert all([op.exists(file) for file in files]) is True
yield files yield files
# Note dir will cleanup the files # Note dir will cleanup the files
@ -66,6 +69,19 @@ def _file_not_found(dir, fcn):
pytest.raises(OSError, fcn, file) pytest.raises(OSError, fcn, file)
def _multi_byte_unicode(dir, fcn):
single_file = op.join(dir, "😇.txt")
_create_tree(single_file)
assert op.exists(single_file) is True
fcn(single_file)
assert op.exists(single_file) is False
files = [op.join(dir, "😇{}.txt".format(index)) for index in range(10)]
[_create_tree(file) for file in files]
assert all([op.exists(file) for file in files]) is True
fcn(files)
assert any([op.exists(file) for file in files]) is False
def test_trash_folder(testdir): def test_trash_folder(testdir):
_trash_folder(testdir, s2t) _trash_folder(testdir, s2t)
@ -98,6 +114,10 @@ def test_file_not_found_modern(testdir):
_file_not_found(testdir, s2t_modern) _file_not_found(testdir, s2t_modern)
def test_multi_byte_unicode_modern(testdir):
_multi_byte_unicode(testdir, s2t_modern)
def test_trash_folder_legacy(testdir): def test_trash_folder_legacy(testdir):
_trash_folder(testdir, s2t_legacy) _trash_folder(testdir, s2t_legacy)
@ -114,6 +134,10 @@ def test_file_not_found_legacy(testdir):
_file_not_found(testdir, s2t_legacy) _file_not_found(testdir, s2t_legacy)
def test_multi_byte_unicode_legacy(testdir):
_multi_byte_unicode(testdir, s2t_legacy)
# Long path tests # Long path tests
@pytest.fixture @pytest.fixture
def longdir(tmp_path): def longdir(tmp_path):
@ -129,6 +153,7 @@ def longfile(longdir):
path = op.join(longdir, name + "{}.txt") path = op.join(longdir, name + "{}.txt")
file = path.format("") file = path.format("")
_create_tree(file) _create_tree(file)
assert op.exists(file) is True
yield file yield file
@ -138,11 +163,14 @@ def longfiles(longdir):
path = op.join(longdir, name + "{}.txt") path = op.join(longdir, name + "{}.txt")
files = [path.format(index) for index in range(10)] files = [path.format(index) for index in range(10)]
[_create_tree(file) for file in files] [_create_tree(file) for file in files]
assert all([op.exists(file) for file in files]) is True
yield files yield files
# NOTE: both legacy and modern test "pass" on windows, but actually are not moving files to the # NOTE: both legacy and modern test "pass" on windows, however sometimes with the same path
# recycle bin, this was tested on latest windows 10, thought to have worked previously # they do not actually recycle files but delete them. Noticed this when testing with the
# recycle bin open, noticed later tests actually worked, modern version can actually detect
# when this happens but not stop it at this moment, and we need a way to verify it when testing.
def test_trash_long_file_modern(longfile): def test_trash_long_file_modern(longfile):
_trash_file(longfile, s2t_modern) _trash_file(longfile, s2t_modern)

View File

@ -18,6 +18,8 @@ def file():
dir=op.expanduser("~"), prefix="send2trash_test", delete=False dir=op.expanduser("~"), prefix="send2trash_test", delete=False
) )
file.close() file.close()
# Verify file was actually created
assert op.exists(file.name) is True
yield file.name yield file.name
# Cleanup trash files on supported platforms # Cleanup trash files on supported platforms
if sys.platform != "win32": if sys.platform != "win32":