mirror of
https://github.com/arsenetar/dupeguru.git
synced 2026-01-22 06:37:17 +00:00
[#89 state:fixed] Added a Folders scan type in dgse.
--HG-- rename : core_se/tests/fs_test.py => core/tests/fs_test.py
This commit is contained in:
@@ -122,52 +122,52 @@ def test_states():
|
||||
d = Directories()
|
||||
p = testpath + 'onefile'
|
||||
d.add_path(p)
|
||||
eq_(STATE_NORMAL,d.get_state(p))
|
||||
d.set_state(p,STATE_REFERENCE)
|
||||
eq_(STATE_REFERENCE,d.get_state(p))
|
||||
eq_(STATE_REFERENCE,d.get_state(p + 'dir1'))
|
||||
eq_(DirectoryState.Normal ,d.get_state(p))
|
||||
d.set_state(p, DirectoryState.Reference)
|
||||
eq_(DirectoryState.Reference ,d.get_state(p))
|
||||
eq_(DirectoryState.Reference ,d.get_state(p + 'dir1'))
|
||||
eq_(1,len(d.states))
|
||||
eq_(p,list(d.states.keys())[0])
|
||||
eq_(STATE_REFERENCE,d.states[p])
|
||||
eq_(DirectoryState.Reference ,d.states[p])
|
||||
|
||||
def test_get_state_with_path_not_there():
|
||||
# When the path's not there, just return STATE_NORMAL
|
||||
# When the path's not there, just return DirectoryState.Normal
|
||||
d = Directories()
|
||||
d.add_path(testpath + 'onefile')
|
||||
eq_(d.get_state(testpath), STATE_NORMAL)
|
||||
eq_(d.get_state(testpath), DirectoryState.Normal)
|
||||
|
||||
def test_states_remain_when_larger_directory_eat_smaller_ones():
|
||||
d = Directories()
|
||||
p = testpath + 'onefile'
|
||||
d.add_path(p)
|
||||
d.set_state(p,STATE_EXCLUDED)
|
||||
d.set_state(p, DirectoryState.Excluded)
|
||||
d.add_path(testpath)
|
||||
d.set_state(testpath,STATE_REFERENCE)
|
||||
eq_(STATE_EXCLUDED,d.get_state(p))
|
||||
eq_(STATE_EXCLUDED,d.get_state(p + 'dir1'))
|
||||
eq_(STATE_REFERENCE,d.get_state(testpath))
|
||||
d.set_state(testpath, DirectoryState.Reference)
|
||||
eq_(DirectoryState.Excluded ,d.get_state(p))
|
||||
eq_(DirectoryState.Excluded ,d.get_state(p + 'dir1'))
|
||||
eq_(DirectoryState.Reference ,d.get_state(testpath))
|
||||
|
||||
def test_set_state_keep_state_dict_size_to_minimum():
|
||||
d = Directories()
|
||||
p = testpath + 'fs'
|
||||
d.add_path(p)
|
||||
d.set_state(p,STATE_REFERENCE)
|
||||
d.set_state(p + 'dir1',STATE_REFERENCE)
|
||||
d.set_state(p, DirectoryState.Reference)
|
||||
d.set_state(p + 'dir1', DirectoryState.Reference)
|
||||
eq_(1,len(d.states))
|
||||
eq_(STATE_REFERENCE,d.get_state(p + 'dir1'))
|
||||
d.set_state(p + 'dir1',STATE_NORMAL)
|
||||
eq_(DirectoryState.Reference ,d.get_state(p + 'dir1'))
|
||||
d.set_state(p + 'dir1', DirectoryState.Normal)
|
||||
eq_(2,len(d.states))
|
||||
eq_(STATE_NORMAL,d.get_state(p + 'dir1'))
|
||||
d.set_state(p + 'dir1',STATE_REFERENCE)
|
||||
eq_(DirectoryState.Normal ,d.get_state(p + 'dir1'))
|
||||
d.set_state(p + 'dir1', DirectoryState.Reference)
|
||||
eq_(1,len(d.states))
|
||||
eq_(STATE_REFERENCE,d.get_state(p + 'dir1'))
|
||||
eq_(DirectoryState.Reference ,d.get_state(p + 'dir1'))
|
||||
|
||||
def test_get_files():
|
||||
d = Directories()
|
||||
p = testpath + 'fs'
|
||||
d.add_path(p)
|
||||
d.set_state(p + 'dir1',STATE_REFERENCE)
|
||||
d.set_state(p + 'dir2',STATE_EXCLUDED)
|
||||
d.set_state(p + 'dir1', DirectoryState.Reference)
|
||||
d.set_state(p + 'dir2', DirectoryState.Excluded)
|
||||
files = list(d.get_files())
|
||||
eq_(5, len(files))
|
||||
for f in files:
|
||||
@@ -176,11 +176,26 @@ def test_get_files():
|
||||
else:
|
||||
assert not f.is_ref
|
||||
|
||||
def test_get_folders():
|
||||
d = Directories()
|
||||
p = testpath + 'fs'
|
||||
d.add_path(p)
|
||||
d.set_state(p + 'dir1', DirectoryState.Reference)
|
||||
d.set_state(p + 'dir2', DirectoryState.Excluded)
|
||||
folders = list(d.get_folders())
|
||||
eq_(len(folders), 3)
|
||||
ref = [f for f in folders if f.is_ref]
|
||||
not_ref = [f for f in folders if not f.is_ref]
|
||||
eq_(len(ref), 1)
|
||||
eq_(ref[0].path, p + 'dir1')
|
||||
eq_(len(not_ref), 2)
|
||||
eq_(ref[0].size, 1)
|
||||
|
||||
def test_get_files_with_inherited_exclusion():
|
||||
d = Directories()
|
||||
p = testpath + 'onefile'
|
||||
d.add_path(p)
|
||||
d.set_state(p,STATE_EXCLUDED)
|
||||
d.set_state(p, DirectoryState.Excluded)
|
||||
eq_([], list(d.get_files()))
|
||||
|
||||
def test_save_and_load(tmpdir):
|
||||
@@ -192,14 +207,14 @@ def test_save_and_load(tmpdir):
|
||||
io.mkdir(p2)
|
||||
d1.add_path(p1)
|
||||
d1.add_path(p2)
|
||||
d1.set_state(p1, STATE_REFERENCE)
|
||||
d1.set_state(p1 + 'dir1',STATE_EXCLUDED)
|
||||
d1.set_state(p1, DirectoryState.Reference)
|
||||
d1.set_state(p1 + 'dir1', DirectoryState.Excluded)
|
||||
tmpxml = str(tmpdir.join('directories_testunit.xml'))
|
||||
d1.save_to_file(tmpxml)
|
||||
d2.load_from_file(tmpxml)
|
||||
eq_(2, len(d2))
|
||||
eq_(STATE_REFERENCE,d2.get_state(p1))
|
||||
eq_(STATE_EXCLUDED,d2.get_state(p1 + 'dir1'))
|
||||
eq_(DirectoryState.Reference ,d2.get_state(p1))
|
||||
eq_(DirectoryState.Excluded ,d2.get_state(p1 + 'dir1'))
|
||||
|
||||
def test_invalid_path():
|
||||
d = Directories()
|
||||
@@ -211,7 +226,7 @@ def test_invalid_path():
|
||||
def test_set_state_on_invalid_path():
|
||||
d = Directories()
|
||||
try:
|
||||
d.set_state(Path('foobar',),STATE_NORMAL)
|
||||
d.set_state(Path('foobar',), DirectoryState.Normal)
|
||||
except LookupError:
|
||||
assert False
|
||||
|
||||
@@ -237,7 +252,7 @@ def test_unicode_save(tmpdir):
|
||||
io.mkdir(p1)
|
||||
io.mkdir(p1 + 'foo\xe9')
|
||||
d.add_path(p1)
|
||||
d.set_state(p1 + 'foo\xe9', STATE_EXCLUDED)
|
||||
d.set_state(p1 + 'foo\xe9', DirectoryState.Excluded)
|
||||
tmpxml = str(tmpdir.join('directories_testunit.xml'))
|
||||
try:
|
||||
d.save_to_file(tmpxml)
|
||||
@@ -268,17 +283,17 @@ def test_get_state_returns_excluded_by_default_for_hidden_directories(tmpdir):
|
||||
hidden_dir_path = p + '.foo'
|
||||
io.mkdir(p + '.foo')
|
||||
d.add_path(p)
|
||||
eq_(d.get_state(hidden_dir_path), STATE_EXCLUDED)
|
||||
eq_(d.get_state(hidden_dir_path), DirectoryState.Excluded)
|
||||
# But it can be overriden
|
||||
d.set_state(hidden_dir_path, STATE_NORMAL)
|
||||
eq_(d.get_state(hidden_dir_path), STATE_NORMAL)
|
||||
d.set_state(hidden_dir_path, DirectoryState.Normal)
|
||||
eq_(d.get_state(hidden_dir_path), DirectoryState.Normal)
|
||||
|
||||
def test_default_path_state_override(tmpdir):
|
||||
# It's possible for a subclass to override the default state of a path
|
||||
class MyDirectories(Directories):
|
||||
def _default_state_for_path(self, path):
|
||||
if 'foobar' in path:
|
||||
return STATE_EXCLUDED
|
||||
return DirectoryState.Excluded
|
||||
|
||||
d = MyDirectories()
|
||||
p1 = Path(str(tmpdir))
|
||||
@@ -287,11 +302,11 @@ def test_default_path_state_override(tmpdir):
|
||||
io.mkdir(p1 + 'foobaz')
|
||||
io.open(p1 + 'foobaz/somefile', 'w').close()
|
||||
d.add_path(p1)
|
||||
eq_(d.get_state(p1 + 'foobaz'), STATE_NORMAL)
|
||||
eq_(d.get_state(p1 + 'foobar'), STATE_EXCLUDED)
|
||||
eq_(d.get_state(p1 + 'foobaz'), DirectoryState.Normal)
|
||||
eq_(d.get_state(p1 + 'foobar'), DirectoryState.Excluded)
|
||||
eq_(len(list(d.get_files())), 1) # only the 'foobaz' file is there
|
||||
# However, the default state can be changed
|
||||
d.set_state(p1 + 'foobar', STATE_NORMAL)
|
||||
eq_(d.get_state(p1 + 'foobar'), STATE_NORMAL)
|
||||
d.set_state(p1 + 'foobar', DirectoryState.Normal)
|
||||
eq_(d.get_state(p1 + 'foobar'), DirectoryState.Normal)
|
||||
eq_(len(list(d.get_files())), 2)
|
||||
|
||||
|
||||
45
core/tests/fs_test.py
Normal file
45
core/tests/fs_test.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2009-10-23
|
||||
# Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
|
||||
#
|
||||
# This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.hardcoded.net/licenses/bsd_license
|
||||
|
||||
import hashlib
|
||||
|
||||
from hscommon.path import Path
|
||||
from hscommon.testutil import eq_
|
||||
from core.tests.directories_test import create_fake_fs
|
||||
|
||||
from .. import fs
|
||||
|
||||
def test_size_aggregates_subfiles(tmpdir):
|
||||
p = create_fake_fs(Path(str(tmpdir)))
|
||||
b = fs.Folder(p)
|
||||
eq_(b.size, 12)
|
||||
|
||||
def test_md5_aggregate_subfiles_sorted(tmpdir):
|
||||
#dir.allfiles can return child in any order. Thus, bundle.md5 must aggregate
|
||||
#all files' md5 it contains, but it must make sure that it does so in the
|
||||
#same order everytime.
|
||||
p = create_fake_fs(Path(str(tmpdir)))
|
||||
b = fs.Folder(p)
|
||||
md51 = fs.File(p + ('dir1', 'file1.test')).md5
|
||||
md52 = fs.File(p + ('dir2', 'file2.test')).md5
|
||||
md53 = fs.File(p + ('dir3', 'file3.test')).md5
|
||||
md54 = fs.File(p + 'file1.test').md5
|
||||
md55 = fs.File(p + 'file2.test').md5
|
||||
md56 = fs.File(p + 'file3.test').md5
|
||||
# The expected md5 is the md5 of md5s for folders and the direct md5 for files
|
||||
folder_md51 = hashlib.md5(md51).digest()
|
||||
folder_md52 = hashlib.md5(md52).digest()
|
||||
folder_md53 = hashlib.md5(md53).digest()
|
||||
md5 = hashlib.md5(folder_md51+folder_md52+folder_md53+md54+md55+md56)
|
||||
eq_(b.md5, md5.digest())
|
||||
|
||||
def test_has_file_attrs(tmpdir):
|
||||
#a Folder must behave like a file, so it must have mtime attributes
|
||||
b = fs.Folder(Path(str(tmpdir)))
|
||||
assert b.mtime > 0
|
||||
eq_(b.extension, '')
|
||||
@@ -471,3 +471,27 @@ def test_dont_group_files_that_dont_exist(tmpdir):
|
||||
s._getmatches = getmatches
|
||||
|
||||
assert not s.GetDupeGroups([file1, file2])
|
||||
|
||||
def test_folder_scan_exclude_subfolder_matches(fake_fileexists):
|
||||
# when doing a Folders scan type, don't include matches for folders whose parent folder already
|
||||
# match.
|
||||
s = Scanner()
|
||||
s.scan_type = ScanType.Folders
|
||||
topf1 = no("top folder 1", size=42)
|
||||
topf1.md5 = topf1.md5partial = b"some_md5_1"
|
||||
topf1.path = Path('/topf1')
|
||||
topf2 = no("top folder 2", size=42)
|
||||
topf2.md5 = topf2.md5partial = b"some_md5_1"
|
||||
topf2.path = Path('/topf2')
|
||||
subf1 = no("sub folder 1", size=41)
|
||||
subf1.md5 = subf1.md5partial = b"some_md5_2"
|
||||
subf1.path = Path('/topf1/sub')
|
||||
subf2 = no("sub folder 2", size=41)
|
||||
subf2.md5 = subf2.md5partial = b"some_md5_2"
|
||||
subf2.path = Path('/topf2/sub')
|
||||
eq_(len(s.GetDupeGroups([topf1, topf2, subf1, subf2])), 1) # only top folders
|
||||
# however, if another folder matches a subfolder, keep in in the matches
|
||||
otherf = no("other folder", size=41)
|
||||
otherf.md5 = otherf.md5partial = b"some_md5_2"
|
||||
otherf.path = Path('/otherfolder')
|
||||
eq_(len(s.GetDupeGroups([topf1, topf2, subf1, subf2, otherf])), 2)
|
||||
|
||||
Reference in New Issue
Block a user