mirror of
https://github.com/arsenetar/dupeguru.git
synced 2024-11-19 05:19:03 +00:00
Apply flake8 checks to tests
This commit is contained in:
parent
9ed4b7abf0
commit
130581db53
@ -160,7 +160,7 @@ class TestCaseDupeGuruWithResults:
|
||||
def pytest_funcarg__do_setup(self, request):
|
||||
app = TestApp()
|
||||
self.app = app.app
|
||||
self.objects,self.matches,self.groups = GetTestGroups()
|
||||
self.objects, self.matches, self.groups = GetTestGroups()
|
||||
self.app.results.groups = self.groups
|
||||
self.dpanel = app.dpanel
|
||||
self.dtree = app.dtree
|
||||
@ -273,7 +273,6 @@ class TestCaseDupeGuruWithResults:
|
||||
# When marking selected dupes with a heterogenous selection, mark all selected dupes. When
|
||||
# it's homogenous, simply toggle.
|
||||
app = self.app
|
||||
objects = self.objects
|
||||
self.rtable.select([1])
|
||||
app.toggle_selected_mark_state()
|
||||
# index 0 is unmarkable, but we throw it in the bunch to be sure that it doesn't make the
|
||||
@ -358,19 +357,19 @@ class TestCaseDupeGuruWithResults:
|
||||
open(p1, 'w').close()
|
||||
open(p2, 'w').close()
|
||||
dne = '/does_not_exist'
|
||||
app.ignore_list.Ignore(dne,p1)
|
||||
app.ignore_list.Ignore(p2,dne)
|
||||
app.ignore_list.Ignore(p1,p2)
|
||||
app.ignore_list.Ignore(dne, p1)
|
||||
app.ignore_list.Ignore(p2, dne)
|
||||
app.ignore_list.Ignore(p1, p2)
|
||||
app.purge_ignore_list()
|
||||
eq_(1,len(app.ignore_list))
|
||||
assert app.ignore_list.AreIgnored(p1,p2)
|
||||
assert not app.ignore_list.AreIgnored(dne,p1)
|
||||
eq_(1, len(app.ignore_list))
|
||||
assert app.ignore_list.AreIgnored(p1, p2)
|
||||
assert not app.ignore_list.AreIgnored(dne, p1)
|
||||
|
||||
def test_only_unicode_is_added_to_ignore_list(self, do_setup):
|
||||
def FakeIgnore(first,second):
|
||||
if not isinstance(first,str):
|
||||
def FakeIgnore(first, second):
|
||||
if not isinstance(first, str):
|
||||
self.fail()
|
||||
if not isinstance(second,str):
|
||||
if not isinstance(second, str):
|
||||
self.fail()
|
||||
|
||||
app = self.app
|
||||
@ -400,8 +399,6 @@ class TestCaseDupeGuruWithResults:
|
||||
def test_dont_crash_on_delta_powermarker_dupecount_sort(self, do_setup):
|
||||
# Don't crash when sorting by dupe count or percentage while delta+powermarker are enabled.
|
||||
# Ref #238
|
||||
app = self.app
|
||||
objects = self.objects
|
||||
self.rtable.delta_values = True
|
||||
self.rtable.power_marker = True
|
||||
self.rtable.sort('dupe_count', False)
|
||||
@ -414,11 +411,11 @@ class TestCaseDupeGuru_renameSelected:
|
||||
def pytest_funcarg__do_setup(self, request):
|
||||
tmpdir = request.getfuncargvalue('tmpdir')
|
||||
p = Path(str(tmpdir))
|
||||
fp = open(str(p['foo bar 1']),mode='w')
|
||||
fp = open(str(p['foo bar 1']), mode='w')
|
||||
fp.close()
|
||||
fp = open(str(p['foo bar 2']),mode='w')
|
||||
fp = open(str(p['foo bar 2']), mode='w')
|
||||
fp.close()
|
||||
fp = open(str(p['foo bar 3']),mode='w')
|
||||
fp = open(str(p['foo bar 3']), mode='w')
|
||||
fp.close()
|
||||
files = fs.get_files(p)
|
||||
for f in files:
|
||||
@ -426,7 +423,7 @@ class TestCaseDupeGuru_renameSelected:
|
||||
matches = engine.getmatches(files)
|
||||
groups = engine.get_groups(matches)
|
||||
g = groups[0]
|
||||
g.prioritize(lambda x:x.name)
|
||||
g.prioritize(lambda x: x.name)
|
||||
app = TestApp()
|
||||
app.app.results.groups = groups
|
||||
self.app = app.app
|
||||
|
@ -1,12 +1,10 @@
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2011/09/07
|
||||
# Copyright 2015 Hardcoded Software (http://www.hardcoded.net)
|
||||
# Copyright 2016 Hardcoded Software (http://www.hardcoded.net)
|
||||
#
|
||||
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
from hscommon.testutil import TestApp as TestAppBase, eq_, with_app
|
||||
from hscommon.testutil import TestApp as TestAppBase, eq_, with_app # noqa
|
||||
from hscommon.path import Path
|
||||
from hscommon.util import get_file_ext, format_size
|
||||
from hscommon.gui.column import Column
|
||||
@ -15,9 +13,7 @@ from hscommon.jobprogress.job import nulljob, JobCancelled
|
||||
from .. import engine
|
||||
from .. import prioritize
|
||||
from ..engine import getwords
|
||||
from ..app import DupeGuru as DupeGuruBase, cmp_value
|
||||
from ..gui.details_panel import DetailsPanel
|
||||
from ..gui.directory_tree import DirectoryTree
|
||||
from ..app import DupeGuru as DupeGuruBase
|
||||
from ..gui.result_table import ResultTable as ResultTableBase
|
||||
from ..gui.prioritize_dialog import PrioritizeDialog
|
||||
|
||||
@ -119,14 +115,20 @@ class NamedObject:
|
||||
# "ibabtu" (1)
|
||||
# "ibabtu" (1)
|
||||
def GetTestGroups():
|
||||
objects = [NamedObject("foo bar"),NamedObject("bar bleh"),NamedObject("foo bleh"),NamedObject("ibabtu"),NamedObject("ibabtu")]
|
||||
objects = [
|
||||
NamedObject("foo bar"),
|
||||
NamedObject("bar bleh"),
|
||||
NamedObject("foo bleh"),
|
||||
NamedObject("ibabtu"),
|
||||
NamedObject("ibabtu")
|
||||
]
|
||||
objects[1].size = 1024
|
||||
matches = engine.getmatches(objects) #we should have 5 matches
|
||||
groups = engine.get_groups(matches) #We should have 2 groups
|
||||
for g in groups:
|
||||
g.prioritize(lambda x:objects.index(x)) #We want the dupes to be in the same order as the list is
|
||||
g.prioritize(lambda x: objects.index(x)) #We want the dupes to be in the same order as the list is
|
||||
groups.sort(key=len, reverse=True) # We want the group with 3 members to be first.
|
||||
return (objects,matches,groups)
|
||||
return (objects, matches, groups)
|
||||
|
||||
class TestApp(TestAppBase):
|
||||
def __init__(self):
|
||||
@ -137,7 +139,6 @@ class TestApp(TestAppBase):
|
||||
return gui
|
||||
|
||||
TestAppBase.__init__(self)
|
||||
make_gui = self.make_gui
|
||||
self.app = DupeGuru()
|
||||
self.default_parent = self.app
|
||||
self.rtable = link_gui(self.app.result_table)
|
||||
|
@ -1 +1 @@
|
||||
from hscommon.testutil import pytest_funcarg__app
|
||||
from hscommon.testutil import pytest_funcarg__app # noqa
|
||||
|
@ -1,9 +1,7 @@
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2006/02/27
|
||||
# Copyright 2015 Hardcoded Software (http://www.hardcoded.net)
|
||||
#
|
||||
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# Copyright 2016 Hardcoded Software (http://www.hardcoded.net)
|
||||
#
|
||||
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
import os
|
||||
@ -15,7 +13,7 @@ from pytest import raises
|
||||
from hscommon.path import Path
|
||||
from hscommon.testutil import eq_
|
||||
|
||||
from ..directories import *
|
||||
from ..directories import Directories, DirectoryState, AlreadyThereError, InvalidPathError
|
||||
|
||||
def create_fake_fs(rootpath):
|
||||
# We have it as a separate function because other units are using it.
|
||||
@ -44,6 +42,8 @@ def create_fake_fs(rootpath):
|
||||
fp.close()
|
||||
return rootpath
|
||||
|
||||
testpath = None
|
||||
|
||||
def setup_module(module):
|
||||
# In this unit, we have tests depending on two directory structure. One with only one file in it
|
||||
# and another with a more complex structure.
|
||||
@ -68,13 +68,13 @@ def test_add_path():
|
||||
d = Directories()
|
||||
p = testpath['onefile']
|
||||
d.add_path(p)
|
||||
eq_(1,len(d))
|
||||
eq_(1, len(d))
|
||||
assert p in d
|
||||
assert (p['foobar']) in d
|
||||
assert p.parent() not in d
|
||||
p = testpath['fs']
|
||||
d.add_path(p)
|
||||
eq_(2,len(d))
|
||||
eq_(2, len(d))
|
||||
assert p in d
|
||||
|
||||
def test_AddPath_when_path_is_already_there():
|
||||
@ -96,14 +96,14 @@ def test_add_path_containing_paths_already_there():
|
||||
eq_(d[0], testpath)
|
||||
|
||||
def test_AddPath_non_latin(tmpdir):
|
||||
p = Path(str(tmpdir))
|
||||
to_add = p['unicode\u201a']
|
||||
os.mkdir(str(to_add))
|
||||
d = Directories()
|
||||
try:
|
||||
d.add_path(to_add)
|
||||
except UnicodeDecodeError:
|
||||
assert False
|
||||
p = Path(str(tmpdir))
|
||||
to_add = p['unicode\u201a']
|
||||
os.mkdir(str(to_add))
|
||||
d = Directories()
|
||||
try:
|
||||
d.add_path(to_add)
|
||||
except UnicodeDecodeError:
|
||||
assert False
|
||||
|
||||
def test_del():
|
||||
d = Directories()
|
||||
@ -121,13 +121,13 @@ def test_states():
|
||||
d = Directories()
|
||||
p = testpath['onefile']
|
||||
d.add_path(p)
|
||||
eq_(DirectoryState.Normal ,d.get_state(p))
|
||||
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_(DirectoryState.Reference ,d.states[p])
|
||||
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_(DirectoryState.Reference, d.states[p])
|
||||
|
||||
def test_get_state_with_path_not_there():
|
||||
# When the path's not there, just return DirectoryState.Normal
|
||||
@ -199,8 +199,8 @@ def test_save_and_load(tmpdir):
|
||||
d1.save_to_file(tmpxml)
|
||||
d2.load_from_file(tmpxml)
|
||||
eq_(2, len(d2))
|
||||
eq_(DirectoryState.Reference ,d2.get_state(p1))
|
||||
eq_(DirectoryState.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()
|
||||
@ -280,7 +280,7 @@ def test_default_path_state_override(tmpdir):
|
||||
def _default_state_for_path(self, path):
|
||||
if 'foobar' in path:
|
||||
return DirectoryState.Excluded
|
||||
|
||||
|
||||
d = MyDirectories()
|
||||
p1 = Path(str(tmpdir))
|
||||
p1['foobar'].mkdir()
|
||||
|
@ -1,6 +1,4 @@
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2006/01/29
|
||||
# Copyright 2015 Hardcoded Software (http://www.hardcoded.net)
|
||||
# Copyright 2016 Hardcoded Software (http://www.hardcoded.net)
|
||||
#
|
||||
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
@ -14,7 +12,11 @@ from hscommon.testutil import eq_, log_calls
|
||||
|
||||
from .base import NamedObject
|
||||
from .. import engine
|
||||
from ..engine import *
|
||||
from ..engine import (
|
||||
get_match, getwords, Group, getfields, unpack_fields, compare_fields, compare, WEIGHT_WORDS,
|
||||
MATCH_SIMILAR_WORDS, NO_FIELD_ORDER, build_word_dict, get_groups, getmatches, Match,
|
||||
getmatches_by_contents, merge_similar_words, reduce_common_words
|
||||
)
|
||||
|
||||
no = NamedObject
|
||||
|
||||
@ -22,9 +24,9 @@ def get_match_triangle():
|
||||
o1 = NamedObject(with_words=True)
|
||||
o2 = NamedObject(with_words=True)
|
||||
o3 = NamedObject(with_words=True)
|
||||
m1 = get_match(o1,o2)
|
||||
m2 = get_match(o1,o3)
|
||||
m3 = get_match(o2,o3)
|
||||
m1 = get_match(o1, o2)
|
||||
m2 = get_match(o1, o3)
|
||||
m3 = get_match(o2, o3)
|
||||
return [m1, m2, m3]
|
||||
|
||||
def get_test_group():
|
||||
@ -51,7 +53,7 @@ class TestCasegetwords:
|
||||
|
||||
def test_splitter_chars(self):
|
||||
eq_(
|
||||
[chr(i) for i in range(ord('a'),ord('z')+1)],
|
||||
[chr(i) for i in range(ord('a'), ord('z')+1)],
|
||||
getwords("a-b_c&d+e(f)g;h\\i[j]k{l}m:n.o,p<q>r/s?t~u!v@w#x$y*z")
|
||||
)
|
||||
|
||||
@ -99,8 +101,8 @@ class TestCaseunpack_fields:
|
||||
|
||||
class TestCaseWordCompare:
|
||||
def test_list(self):
|
||||
eq_(100, compare(['a', 'b', 'c', 'd'],['a', 'b', 'c', 'd']))
|
||||
eq_(86, compare(['a', 'b', 'c', 'd'],['a', 'b', 'c']))
|
||||
eq_(100, compare(['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'd']))
|
||||
eq_(86, compare(['a', 'b', 'c', 'd'], ['a', 'b', 'c']))
|
||||
|
||||
def test_unordered(self):
|
||||
#Sometimes, users don't want fuzzy matching too much When they set the slider
|
||||
@ -123,7 +125,7 @@ class TestCaseWordCompare:
|
||||
eq_(int((6.0 / 13.0) * 100), compare(['foo', 'bar'], ['bar', 'bleh'], (WEIGHT_WORDS, )))
|
||||
|
||||
def test_similar_words(self):
|
||||
eq_(100, compare(['the', 'white', 'stripes'],['the', 'whites', 'stripe'], (MATCH_SIMILAR_WORDS, )))
|
||||
eq_(100, compare(['the', 'white', 'stripes'], ['the', 'whites', 'stripe'], (MATCH_SIMILAR_WORDS, )))
|
||||
|
||||
def test_empty(self):
|
||||
eq_(0, compare([], []))
|
||||
@ -154,7 +156,7 @@ class TestCaseWordCompareWithFields:
|
||||
eq_((0, 1, 2, 3, 5), flags)
|
||||
|
||||
monkeypatch.setattr(engine, 'compare_fields', mock_compare)
|
||||
compare_fields([['a']], [['a']],(0, 1, 2, 3, 5))
|
||||
compare_fields([['a']], [['a']], (0, 1, 2, 3, 5))
|
||||
|
||||
def test_order(self):
|
||||
first = [['a', 'b'], ['c', 'd', 'e']]
|
||||
@ -162,124 +164,124 @@ class TestCaseWordCompareWithFields:
|
||||
eq_(0, compare_fields(first, second))
|
||||
|
||||
def test_no_order(self):
|
||||
first = [['a','b'],['c','d','e']]
|
||||
second = [['c','d','f'],['a','b']]
|
||||
first = [['a', 'b'], ['c', 'd', 'e']]
|
||||
second = [['c', 'd', 'f'], ['a', 'b']]
|
||||
eq_(67, compare_fields(first, second, (NO_FIELD_ORDER, )))
|
||||
first = [['a','b'],['a','b']] #a field can only be matched once.
|
||||
second = [['c','d','f'],['a','b']]
|
||||
first = [['a', 'b'], ['a', 'b']] #a field can only be matched once.
|
||||
second = [['c', 'd', 'f'], ['a', 'b']]
|
||||
eq_(0, compare_fields(first, second, (NO_FIELD_ORDER, )))
|
||||
first = [['a','b'],['a','b','c']]
|
||||
second = [['c','d','f'],['a','b']]
|
||||
first = [['a', 'b'], ['a', 'b', 'c']]
|
||||
second = [['c', 'd', 'f'], ['a', 'b']]
|
||||
eq_(33, compare_fields(first, second, (NO_FIELD_ORDER, )))
|
||||
|
||||
def test_compare_fields_without_order_doesnt_alter_fields(self):
|
||||
#The NO_ORDER comp type altered the fields!
|
||||
first = [['a','b'],['c','d','e']]
|
||||
second = [['c','d','f'],['a','b']]
|
||||
first = [['a', 'b'], ['c', 'd', 'e']]
|
||||
second = [['c', 'd', 'f'], ['a', 'b']]
|
||||
eq_(67, compare_fields(first, second, (NO_FIELD_ORDER, )))
|
||||
eq_([['a','b'],['c','d','e']],first)
|
||||
eq_([['c','d','f'],['a','b']],second)
|
||||
eq_([['a', 'b'], ['c', 'd', 'e']], first)
|
||||
eq_([['c', 'd', 'f'], ['a', 'b']], second)
|
||||
|
||||
|
||||
class TestCasebuild_word_dict:
|
||||
def test_with_standard_words(self):
|
||||
l = [NamedObject('foo bar',True)]
|
||||
l.append(NamedObject('bar baz',True))
|
||||
l.append(NamedObject('baz bleh foo',True))
|
||||
l = [NamedObject('foo bar', True)]
|
||||
l.append(NamedObject('bar baz', True))
|
||||
l.append(NamedObject('baz bleh foo', True))
|
||||
d = build_word_dict(l)
|
||||
eq_(4,len(d))
|
||||
eq_(2,len(d['foo']))
|
||||
eq_(4, len(d))
|
||||
eq_(2, len(d['foo']))
|
||||
assert l[0] in d['foo']
|
||||
assert l[2] in d['foo']
|
||||
eq_(2,len(d['bar']))
|
||||
eq_(2, len(d['bar']))
|
||||
assert l[0] in d['bar']
|
||||
assert l[1] in d['bar']
|
||||
eq_(2,len(d['baz']))
|
||||
eq_(2, len(d['baz']))
|
||||
assert l[1] in d['baz']
|
||||
assert l[2] in d['baz']
|
||||
eq_(1,len(d['bleh']))
|
||||
eq_(1, len(d['bleh']))
|
||||
assert l[2] in d['bleh']
|
||||
|
||||
def test_unpack_fields(self):
|
||||
o = NamedObject('')
|
||||
o.words = [['foo','bar'],['baz']]
|
||||
o.words = [['foo', 'bar'], ['baz']]
|
||||
d = build_word_dict([o])
|
||||
eq_(3,len(d))
|
||||
eq_(1,len(d['foo']))
|
||||
eq_(3, len(d))
|
||||
eq_(1, len(d['foo']))
|
||||
|
||||
def test_words_are_unaltered(self):
|
||||
o = NamedObject('')
|
||||
o.words = [['foo','bar'],['baz']]
|
||||
o.words = [['foo', 'bar'], ['baz']]
|
||||
build_word_dict([o])
|
||||
eq_([['foo','bar'],['baz']],o.words)
|
||||
eq_([['foo', 'bar'], ['baz']], o.words)
|
||||
|
||||
def test_object_instances_can_only_be_once_in_words_object_list(self):
|
||||
o = NamedObject('foo foo',True)
|
||||
o = NamedObject('foo foo', True)
|
||||
d = build_word_dict([o])
|
||||
eq_(1,len(d['foo']))
|
||||
eq_(1, len(d['foo']))
|
||||
|
||||
def test_job(self):
|
||||
def do_progress(p,d=''):
|
||||
def do_progress(p, d=''):
|
||||
self.log.append(p)
|
||||
return True
|
||||
|
||||
j = job.Job(1,do_progress)
|
||||
j = job.Job(1, do_progress)
|
||||
self.log = []
|
||||
s = "foo bar"
|
||||
build_word_dict([NamedObject(s, True), NamedObject(s, True), NamedObject(s, True)], j)
|
||||
# We don't have intermediate log because iter_with_progress is called with every > 1
|
||||
eq_(0,self.log[0])
|
||||
eq_(100,self.log[1])
|
||||
eq_(0, self.log[0])
|
||||
eq_(100, self.log[1])
|
||||
|
||||
|
||||
class TestCasemerge_similar_words:
|
||||
def test_some_similar_words(self):
|
||||
d = {
|
||||
'foobar':set([1]),
|
||||
'foobar1':set([2]),
|
||||
'foobar2':set([3]),
|
||||
'foobar': set([1]),
|
||||
'foobar1': set([2]),
|
||||
'foobar2': set([3]),
|
||||
}
|
||||
merge_similar_words(d)
|
||||
eq_(1,len(d))
|
||||
eq_(3,len(d['foobar']))
|
||||
eq_(1, len(d))
|
||||
eq_(3, len(d['foobar']))
|
||||
|
||||
|
||||
|
||||
class TestCasereduce_common_words:
|
||||
def test_typical(self):
|
||||
d = {
|
||||
'foo': set([NamedObject('foo bar',True) for i in range(50)]),
|
||||
'bar': set([NamedObject('foo bar',True) for i in range(49)])
|
||||
'foo': set([NamedObject('foo bar', True) for i in range(50)]),
|
||||
'bar': set([NamedObject('foo bar', True) for i in range(49)])
|
||||
}
|
||||
reduce_common_words(d, 50)
|
||||
assert 'foo' not in d
|
||||
eq_(49,len(d['bar']))
|
||||
eq_(49, len(d['bar']))
|
||||
|
||||
def test_dont_remove_objects_with_only_common_words(self):
|
||||
d = {
|
||||
'common': set([NamedObject("common uncommon",True) for i in range(50)] + [NamedObject("common",True)]),
|
||||
'uncommon': set([NamedObject("common uncommon",True)])
|
||||
'common': set([NamedObject("common uncommon", True) for i in range(50)] + [NamedObject("common", True)]),
|
||||
'uncommon': set([NamedObject("common uncommon", True)])
|
||||
}
|
||||
reduce_common_words(d, 50)
|
||||
eq_(1,len(d['common']))
|
||||
eq_(1,len(d['uncommon']))
|
||||
eq_(1, len(d['common']))
|
||||
eq_(1, len(d['uncommon']))
|
||||
|
||||
def test_values_still_are_set_instances(self):
|
||||
d = {
|
||||
'common': set([NamedObject("common uncommon",True) for i in range(50)] + [NamedObject("common",True)]),
|
||||
'uncommon': set([NamedObject("common uncommon",True)])
|
||||
'common': set([NamedObject("common uncommon", True) for i in range(50)] + [NamedObject("common", True)]),
|
||||
'uncommon': set([NamedObject("common uncommon", True)])
|
||||
}
|
||||
reduce_common_words(d, 50)
|
||||
assert isinstance(d['common'],set)
|
||||
assert isinstance(d['uncommon'],set)
|
||||
assert isinstance(d['common'], set)
|
||||
assert isinstance(d['uncommon'], set)
|
||||
|
||||
def test_dont_raise_KeyError_when_a_word_has_been_removed(self):
|
||||
#If a word has been removed by the reduce, an object in a subsequent common word that
|
||||
#contains the word that has been removed would cause a KeyError.
|
||||
d = {
|
||||
'foo': set([NamedObject('foo bar baz',True) for i in range(50)]),
|
||||
'bar': set([NamedObject('foo bar baz',True) for i in range(50)]),
|
||||
'baz': set([NamedObject('foo bar baz',True) for i in range(49)])
|
||||
'foo': set([NamedObject('foo bar baz', True) for i in range(50)]),
|
||||
'bar': set([NamedObject('foo bar baz', True) for i in range(50)]),
|
||||
'baz': set([NamedObject('foo bar baz', True) for i in range(49)])
|
||||
}
|
||||
try:
|
||||
reduce_common_words(d, 50)
|
||||
@ -290,7 +292,7 @@ class TestCasereduce_common_words:
|
||||
#object.words may be fields.
|
||||
def create_it():
|
||||
o = NamedObject('')
|
||||
o.words = [['foo','bar'],['baz']]
|
||||
o.words = [['foo', 'bar'], ['baz']]
|
||||
return o
|
||||
|
||||
d = {
|
||||
@ -306,39 +308,40 @@ class TestCasereduce_common_words:
|
||||
#be counted as a common word for subsequent words. For example, if 'foo' is processed
|
||||
#as a common word, keeping a "foo bar" file in it, and the 'bar' is processed, "foo bar"
|
||||
#would not stay in 'bar' because 'foo' is not a common word anymore.
|
||||
only_common = NamedObject('foo bar',True)
|
||||
only_common = NamedObject('foo bar', True)
|
||||
d = {
|
||||
'foo': set([NamedObject('foo bar baz',True) for i in range(49)] + [only_common]),
|
||||
'bar': set([NamedObject('foo bar baz',True) for i in range(49)] + [only_common]),
|
||||
'baz': set([NamedObject('foo bar baz',True) for i in range(49)])
|
||||
'foo': set([NamedObject('foo bar baz', True) for i in range(49)] + [only_common]),
|
||||
'bar': set([NamedObject('foo bar baz', True) for i in range(49)] + [only_common]),
|
||||
'baz': set([NamedObject('foo bar baz', True) for i in range(49)])
|
||||
}
|
||||
reduce_common_words(d, 50)
|
||||
eq_(1,len(d['foo']))
|
||||
eq_(1,len(d['bar']))
|
||||
eq_(49,len(d['baz']))
|
||||
eq_(1, len(d['foo']))
|
||||
eq_(1, len(d['bar']))
|
||||
eq_(49, len(d['baz']))
|
||||
|
||||
|
||||
class TestCaseget_match:
|
||||
def test_simple(self):
|
||||
o1 = NamedObject("foo bar",True)
|
||||
o2 = NamedObject("bar bleh",True)
|
||||
m = get_match(o1,o2)
|
||||
eq_(50,m.percentage)
|
||||
eq_(['foo','bar'],m.first.words)
|
||||
eq_(['bar','bleh'],m.second.words)
|
||||
o1 = NamedObject("foo bar", True)
|
||||
o2 = NamedObject("bar bleh", True)
|
||||
m = get_match(o1, o2)
|
||||
eq_(50, m.percentage)
|
||||
eq_(['foo', 'bar'], m.first.words)
|
||||
eq_(['bar', 'bleh'], m.second.words)
|
||||
assert m.first is o1
|
||||
assert m.second is o2
|
||||
|
||||
def test_in(self):
|
||||
o1 = NamedObject("foo",True)
|
||||
o2 = NamedObject("bar",True)
|
||||
m = get_match(o1,o2)
|
||||
o1 = NamedObject("foo", True)
|
||||
o2 = NamedObject("bar", True)
|
||||
m = get_match(o1, o2)
|
||||
assert o1 in m
|
||||
assert o2 in m
|
||||
assert object() not in m
|
||||
|
||||
def test_word_weight(self):
|
||||
eq_(int((6.0 / 13.0) * 100),get_match(NamedObject("foo bar",True),NamedObject("bar bleh",True),(WEIGHT_WORDS,)).percentage)
|
||||
m = get_match(NamedObject("foo bar", True), NamedObject("bar bleh", True), (WEIGHT_WORDS, ))
|
||||
eq_(m.percentage, int((6.0 / 13.0) * 100))
|
||||
|
||||
|
||||
class TestCaseGetMatches:
|
||||
@ -346,16 +349,16 @@ class TestCaseGetMatches:
|
||||
eq_(getmatches([]), [])
|
||||
|
||||
def test_simple(self):
|
||||
l = [NamedObject("foo bar"),NamedObject("bar bleh"),NamedObject("a b c foo")]
|
||||
l = [NamedObject("foo bar"), NamedObject("bar bleh"), NamedObject("a b c foo")]
|
||||
r = getmatches(l)
|
||||
eq_(2,len(r))
|
||||
eq_(2, len(r))
|
||||
m = first(m for m in r if m.percentage == 50) #"foo bar" and "bar bleh"
|
||||
assert_match(m, 'foo bar', 'bar bleh')
|
||||
m = first(m for m in r if m.percentage == 33) #"foo bar" and "a b c foo"
|
||||
assert_match(m, 'foo bar', 'a b c foo')
|
||||
|
||||
def test_null_and_unrelated_objects(self):
|
||||
l = [NamedObject("foo bar"),NamedObject("bar bleh"),NamedObject(""),NamedObject("unrelated object")]
|
||||
l = [NamedObject("foo bar"), NamedObject("bar bleh"), NamedObject(""), NamedObject("unrelated object")]
|
||||
r = getmatches(l)
|
||||
eq_(len(r), 1)
|
||||
m = r[0]
|
||||
@ -363,19 +366,19 @@ class TestCaseGetMatches:
|
||||
assert_match(m, 'foo bar', 'bar bleh')
|
||||
|
||||
def test_twice_the_same_word(self):
|
||||
l = [NamedObject("foo foo bar"),NamedObject("bar bleh")]
|
||||
l = [NamedObject("foo foo bar"), NamedObject("bar bleh")]
|
||||
r = getmatches(l)
|
||||
eq_(1,len(r))
|
||||
eq_(1, len(r))
|
||||
|
||||
def test_twice_the_same_word_when_preworded(self):
|
||||
l = [NamedObject("foo foo bar",True),NamedObject("bar bleh",True)]
|
||||
l = [NamedObject("foo foo bar", True), NamedObject("bar bleh", True)]
|
||||
r = getmatches(l)
|
||||
eq_(1,len(r))
|
||||
eq_(1, len(r))
|
||||
|
||||
def test_two_words_match(self):
|
||||
l = [NamedObject("foo bar"),NamedObject("foo bar bleh")]
|
||||
l = [NamedObject("foo bar"), NamedObject("foo bar bleh")]
|
||||
r = getmatches(l)
|
||||
eq_(1,len(r))
|
||||
eq_(1, len(r))
|
||||
|
||||
def test_match_files_with_only_common_words(self):
|
||||
#If a word occurs more than 50 times, it is excluded from the matching process
|
||||
@ -384,41 +387,41 @@ class TestCaseGetMatches:
|
||||
# This test assumes that the common word threashold const is 50
|
||||
l = [NamedObject("foo") for i in range(50)]
|
||||
r = getmatches(l)
|
||||
eq_(1225,len(r))
|
||||
eq_(1225, len(r))
|
||||
|
||||
def test_use_words_already_there_if_there(self):
|
||||
o1 = NamedObject('foo')
|
||||
o2 = NamedObject('bar')
|
||||
o2.words = ['foo']
|
||||
eq_(1, len(getmatches([o1,o2])))
|
||||
eq_(1, len(getmatches([o1, o2])))
|
||||
|
||||
def test_job(self):
|
||||
def do_progress(p,d=''):
|
||||
def do_progress(p, d=''):
|
||||
self.log.append(p)
|
||||
return True
|
||||
|
||||
j = job.Job(1,do_progress)
|
||||
j = job.Job(1, do_progress)
|
||||
self.log = []
|
||||
s = "foo bar"
|
||||
getmatches([NamedObject(s), NamedObject(s), NamedObject(s)], j=j)
|
||||
assert len(self.log) > 2
|
||||
eq_(0,self.log[0])
|
||||
eq_(100,self.log[-1])
|
||||
eq_(0, self.log[0])
|
||||
eq_(100, self.log[-1])
|
||||
|
||||
def test_weight_words(self):
|
||||
l = [NamedObject("foo bar"),NamedObject("bar bleh")]
|
||||
l = [NamedObject("foo bar"), NamedObject("bar bleh")]
|
||||
m = getmatches(l, weight_words=True)[0]
|
||||
eq_(int((6.0 / 13.0) * 100),m.percentage)
|
||||
eq_(int((6.0 / 13.0) * 100), m.percentage)
|
||||
|
||||
def test_similar_word(self):
|
||||
l = [NamedObject("foobar"),NamedObject("foobars")]
|
||||
l = [NamedObject("foobar"), NamedObject("foobars")]
|
||||
eq_(len(getmatches(l, match_similar_words=True)), 1)
|
||||
eq_(getmatches(l, match_similar_words=True)[0].percentage, 100)
|
||||
l = [NamedObject("foobar"),NamedObject("foo")]
|
||||
l = [NamedObject("foobar"), NamedObject("foo")]
|
||||
eq_(len(getmatches(l, match_similar_words=True)), 0) #too far
|
||||
l = [NamedObject("bizkit"),NamedObject("bizket")]
|
||||
l = [NamedObject("bizkit"), NamedObject("bizket")]
|
||||
eq_(len(getmatches(l, match_similar_words=True)), 1)
|
||||
l = [NamedObject("foobar"),NamedObject("foosbar")]
|
||||
l = [NamedObject("foobar"), NamedObject("foosbar")]
|
||||
eq_(len(getmatches(l, match_similar_words=True)), 1)
|
||||
|
||||
def test_single_object_with_similar_words(self):
|
||||
@ -426,9 +429,9 @@ class TestCaseGetMatches:
|
||||
eq_(len(getmatches(l, match_similar_words=True)), 0)
|
||||
|
||||
def test_double_words_get_counted_only_once(self):
|
||||
l = [NamedObject("foo bar foo bleh"),NamedObject("foo bar bleh bar")]
|
||||
l = [NamedObject("foo bar foo bleh"), NamedObject("foo bar bleh bar")]
|
||||
m = getmatches(l)[0]
|
||||
eq_(75,m.percentage)
|
||||
eq_(75, m.percentage)
|
||||
|
||||
def test_with_fields(self):
|
||||
o1 = NamedObject("foo bar - foo bleh")
|
||||
@ -447,7 +450,7 @@ class TestCaseGetMatches:
|
||||
eq_(m.percentage, 50)
|
||||
|
||||
def test_only_match_similar_when_the_option_is_set(self):
|
||||
l = [NamedObject("foobar"),NamedObject("foobars")]
|
||||
l = [NamedObject("foobar"), NamedObject("foobars")]
|
||||
eq_(len(getmatches(l, match_similar_words=False)), 0)
|
||||
|
||||
def test_dont_recurse_do_match(self):
|
||||
@ -462,9 +465,9 @@ class TestCaseGetMatches:
|
||||
sys.setrecursionlimit(1000)
|
||||
|
||||
def test_min_match_percentage(self):
|
||||
l = [NamedObject("foo bar"),NamedObject("bar bleh"),NamedObject("a b c foo")]
|
||||
l = [NamedObject("foo bar"), NamedObject("bar bleh"), NamedObject("a b c foo")]
|
||||
r = getmatches(l, min_match_percentage=50)
|
||||
eq_(1,len(r)) #Only "foo bar" / "bar bleh" should match
|
||||
eq_(1, len(r)) #Only "foo bar" / "bar bleh" should match
|
||||
|
||||
def test_MemoryError(self, monkeypatch):
|
||||
@log_calls
|
||||
@ -491,112 +494,112 @@ class TestCaseGetMatchesByContents:
|
||||
class TestCaseGroup:
|
||||
def test_empy(self):
|
||||
g = Group()
|
||||
eq_(None,g.ref)
|
||||
eq_([],g.dupes)
|
||||
eq_(0,len(g.matches))
|
||||
eq_(None, g.ref)
|
||||
eq_([], g.dupes)
|
||||
eq_(0, len(g.matches))
|
||||
|
||||
def test_add_match(self):
|
||||
g = Group()
|
||||
m = get_match(NamedObject("foo",True),NamedObject("bar",True))
|
||||
m = get_match(NamedObject("foo", True), NamedObject("bar", True))
|
||||
g.add_match(m)
|
||||
assert g.ref is m.first
|
||||
eq_([m.second],g.dupes)
|
||||
eq_(1,len(g.matches))
|
||||
eq_([m.second], g.dupes)
|
||||
eq_(1, len(g.matches))
|
||||
assert m in g.matches
|
||||
|
||||
def test_multiple_add_match(self):
|
||||
g = Group()
|
||||
o1 = NamedObject("a",True)
|
||||
o2 = NamedObject("b",True)
|
||||
o3 = NamedObject("c",True)
|
||||
o4 = NamedObject("d",True)
|
||||
g.add_match(get_match(o1,o2))
|
||||
o1 = NamedObject("a", True)
|
||||
o2 = NamedObject("b", True)
|
||||
o3 = NamedObject("c", True)
|
||||
o4 = NamedObject("d", True)
|
||||
g.add_match(get_match(o1, o2))
|
||||
assert g.ref is o1
|
||||
eq_([o2],g.dupes)
|
||||
eq_(1,len(g.matches))
|
||||
g.add_match(get_match(o1,o3))
|
||||
eq_([o2],g.dupes)
|
||||
eq_(2,len(g.matches))
|
||||
g.add_match(get_match(o2,o3))
|
||||
eq_([o2,o3],g.dupes)
|
||||
eq_(3,len(g.matches))
|
||||
g.add_match(get_match(o1,o4))
|
||||
eq_([o2,o3],g.dupes)
|
||||
eq_(4,len(g.matches))
|
||||
g.add_match(get_match(o2,o4))
|
||||
eq_([o2,o3],g.dupes)
|
||||
eq_(5,len(g.matches))
|
||||
g.add_match(get_match(o3,o4))
|
||||
eq_([o2,o3,o4],g.dupes)
|
||||
eq_(6,len(g.matches))
|
||||
eq_([o2], g.dupes)
|
||||
eq_(1, len(g.matches))
|
||||
g.add_match(get_match(o1, o3))
|
||||
eq_([o2], g.dupes)
|
||||
eq_(2, len(g.matches))
|
||||
g.add_match(get_match(o2, o3))
|
||||
eq_([o2, o3], g.dupes)
|
||||
eq_(3, len(g.matches))
|
||||
g.add_match(get_match(o1, o4))
|
||||
eq_([o2, o3], g.dupes)
|
||||
eq_(4, len(g.matches))
|
||||
g.add_match(get_match(o2, o4))
|
||||
eq_([o2, o3], g.dupes)
|
||||
eq_(5, len(g.matches))
|
||||
g.add_match(get_match(o3, o4))
|
||||
eq_([o2, o3, o4], g.dupes)
|
||||
eq_(6, len(g.matches))
|
||||
|
||||
def test_len(self):
|
||||
g = Group()
|
||||
eq_(0,len(g))
|
||||
g.add_match(get_match(NamedObject("foo",True),NamedObject("bar",True)))
|
||||
eq_(2,len(g))
|
||||
eq_(0, len(g))
|
||||
g.add_match(get_match(NamedObject("foo", True), NamedObject("bar", True)))
|
||||
eq_(2, len(g))
|
||||
|
||||
def test_add_same_match_twice(self):
|
||||
g = Group()
|
||||
m = get_match(NamedObject("foo",True),NamedObject("foo",True))
|
||||
m = get_match(NamedObject("foo", True), NamedObject("foo", True))
|
||||
g.add_match(m)
|
||||
eq_(2,len(g))
|
||||
eq_(1,len(g.matches))
|
||||
eq_(2, len(g))
|
||||
eq_(1, len(g.matches))
|
||||
g.add_match(m)
|
||||
eq_(2,len(g))
|
||||
eq_(1,len(g.matches))
|
||||
eq_(2, len(g))
|
||||
eq_(1, len(g.matches))
|
||||
|
||||
def test_in(self):
|
||||
g = Group()
|
||||
o1 = NamedObject("foo",True)
|
||||
o2 = NamedObject("bar",True)
|
||||
o1 = NamedObject("foo", True)
|
||||
o2 = NamedObject("bar", True)
|
||||
assert o1 not in g
|
||||
g.add_match(get_match(o1,o2))
|
||||
g.add_match(get_match(o1, o2))
|
||||
assert o1 in g
|
||||
assert o2 in g
|
||||
|
||||
def test_remove(self):
|
||||
g = Group()
|
||||
o1 = NamedObject("foo",True)
|
||||
o2 = NamedObject("bar",True)
|
||||
o3 = NamedObject("bleh",True)
|
||||
g.add_match(get_match(o1,o2))
|
||||
g.add_match(get_match(o1,o3))
|
||||
g.add_match(get_match(o2,o3))
|
||||
eq_(3,len(g.matches))
|
||||
eq_(3,len(g))
|
||||
o1 = NamedObject("foo", True)
|
||||
o2 = NamedObject("bar", True)
|
||||
o3 = NamedObject("bleh", True)
|
||||
g.add_match(get_match(o1, o2))
|
||||
g.add_match(get_match(o1, o3))
|
||||
g.add_match(get_match(o2, o3))
|
||||
eq_(3, len(g.matches))
|
||||
eq_(3, len(g))
|
||||
g.remove_dupe(o3)
|
||||
eq_(1,len(g.matches))
|
||||
eq_(2,len(g))
|
||||
eq_(1, len(g.matches))
|
||||
eq_(2, len(g))
|
||||
g.remove_dupe(o1)
|
||||
eq_(0,len(g.matches))
|
||||
eq_(0,len(g))
|
||||
eq_(0, len(g.matches))
|
||||
eq_(0, len(g))
|
||||
|
||||
def test_remove_with_ref_dupes(self):
|
||||
g = Group()
|
||||
o1 = NamedObject("foo",True)
|
||||
o2 = NamedObject("bar",True)
|
||||
o3 = NamedObject("bleh",True)
|
||||
g.add_match(get_match(o1,o2))
|
||||
g.add_match(get_match(o1,o3))
|
||||
g.add_match(get_match(o2,o3))
|
||||
o1 = NamedObject("foo", True)
|
||||
o2 = NamedObject("bar", True)
|
||||
o3 = NamedObject("bleh", True)
|
||||
g.add_match(get_match(o1, o2))
|
||||
g.add_match(get_match(o1, o3))
|
||||
g.add_match(get_match(o2, o3))
|
||||
o1.is_ref = True
|
||||
o2.is_ref = True
|
||||
g.remove_dupe(o3)
|
||||
eq_(0,len(g))
|
||||
eq_(0, len(g))
|
||||
|
||||
def test_switch_ref(self):
|
||||
o1 = NamedObject(with_words=True)
|
||||
o2 = NamedObject(with_words=True)
|
||||
g = Group()
|
||||
g.add_match(get_match(o1,o2))
|
||||
g.add_match(get_match(o1, o2))
|
||||
assert o1 is g.ref
|
||||
g.switch_ref(o2)
|
||||
assert o2 is g.ref
|
||||
eq_([o1],g.dupes)
|
||||
eq_([o1], g.dupes)
|
||||
g.switch_ref(o2)
|
||||
assert o2 is g.ref
|
||||
g.switch_ref(NamedObject('',True))
|
||||
g.switch_ref(NamedObject('', True))
|
||||
assert o2 is g.ref
|
||||
|
||||
def test_switch_ref_from_ref_dir(self):
|
||||
@ -617,12 +620,12 @@ class TestCaseGroup:
|
||||
m = g.get_match_of(o)
|
||||
assert g.ref in m
|
||||
assert o in m
|
||||
assert g.get_match_of(NamedObject('',True)) is None
|
||||
assert g.get_match_of(NamedObject('', True)) is None
|
||||
assert g.get_match_of(g.ref) is None
|
||||
|
||||
def test_percentage(self):
|
||||
#percentage should return the avg percentage in relation to the ref
|
||||
m1,m2,m3 = get_match_triangle()
|
||||
m1, m2, m3 = get_match_triangle()
|
||||
m1 = Match(m1[0], m1[1], 100)
|
||||
m2 = Match(m2[0], m2[1], 50)
|
||||
m3 = Match(m3[0], m3[1], 33)
|
||||
@ -630,21 +633,21 @@ class TestCaseGroup:
|
||||
g.add_match(m1)
|
||||
g.add_match(m2)
|
||||
g.add_match(m3)
|
||||
eq_(75,g.percentage)
|
||||
eq_(75, g.percentage)
|
||||
g.switch_ref(g.dupes[0])
|
||||
eq_(66,g.percentage)
|
||||
eq_(66, g.percentage)
|
||||
g.remove_dupe(g.dupes[0])
|
||||
eq_(33,g.percentage)
|
||||
eq_(33, g.percentage)
|
||||
g.add_match(m1)
|
||||
g.add_match(m2)
|
||||
eq_(66,g.percentage)
|
||||
eq_(66, g.percentage)
|
||||
|
||||
def test_percentage_on_empty_group(self):
|
||||
g = Group()
|
||||
eq_(0,g.percentage)
|
||||
eq_(0, g.percentage)
|
||||
|
||||
def test_prioritize(self):
|
||||
m1,m2,m3 = get_match_triangle()
|
||||
m1, m2, m3 = get_match_triangle()
|
||||
o1 = m1.first
|
||||
o2 = m1.second
|
||||
o3 = m2.second
|
||||
@ -656,7 +659,7 @@ class TestCaseGroup:
|
||||
g.add_match(m2)
|
||||
g.add_match(m3)
|
||||
assert o1 is g.ref
|
||||
assert g.prioritize(lambda x:x.name)
|
||||
assert g.prioritize(lambda x: x.name)
|
||||
assert o3 is g.ref
|
||||
|
||||
def test_prioritize_with_tie_breaker(self):
|
||||
@ -664,7 +667,7 @@ class TestCaseGroup:
|
||||
g = get_test_group()
|
||||
o1, o2, o3 = g.ordered
|
||||
tie_breaker = lambda ref, dupe: dupe is o3
|
||||
g.prioritize(lambda x:0, tie_breaker)
|
||||
g.prioritize(lambda x: 0, tie_breaker)
|
||||
assert g.ref is o3
|
||||
|
||||
def test_prioritize_with_tie_breaker_runs_on_all_dupes(self):
|
||||
@ -676,7 +679,7 @@ class TestCaseGroup:
|
||||
o2.foo = 2
|
||||
o3.foo = 3
|
||||
tie_breaker = lambda ref, dupe: dupe.foo > ref.foo
|
||||
g.prioritize(lambda x:0, tie_breaker)
|
||||
g.prioritize(lambda x: 0, tie_breaker)
|
||||
assert g.ref is o3
|
||||
|
||||
def test_prioritize_with_tie_breaker_runs_only_on_tie_dupes(self):
|
||||
@ -709,65 +712,65 @@ class TestCaseGroup:
|
||||
g[0].name = 'a'
|
||||
g[1].name = 'b'
|
||||
g[2].name = 'c'
|
||||
assert not g.prioritize(lambda x:x.name)
|
||||
assert not g.prioritize(lambda x: x.name)
|
||||
|
||||
def test_list_like(self):
|
||||
g = Group()
|
||||
o1,o2 = (NamedObject("foo",True),NamedObject("bar",True))
|
||||
g.add_match(get_match(o1,o2))
|
||||
o1, o2 = (NamedObject("foo", True), NamedObject("bar", True))
|
||||
g.add_match(get_match(o1, o2))
|
||||
assert g[0] is o1
|
||||
assert g[1] is o2
|
||||
|
||||
def test_discard_matches(self):
|
||||
g = Group()
|
||||
o1,o2,o3 = (NamedObject("foo",True),NamedObject("bar",True),NamedObject("baz",True))
|
||||
g.add_match(get_match(o1,o2))
|
||||
g.add_match(get_match(o1,o3))
|
||||
o1, o2, o3 = (NamedObject("foo", True), NamedObject("bar", True), NamedObject("baz", True))
|
||||
g.add_match(get_match(o1, o2))
|
||||
g.add_match(get_match(o1, o3))
|
||||
g.discard_matches()
|
||||
eq_(1,len(g.matches))
|
||||
eq_(0,len(g.candidates))
|
||||
eq_(1, len(g.matches))
|
||||
eq_(0, len(g.candidates))
|
||||
|
||||
|
||||
class TestCaseget_groups:
|
||||
def test_empty(self):
|
||||
r = get_groups([])
|
||||
eq_([],r)
|
||||
eq_([], r)
|
||||
|
||||
def test_simple(self):
|
||||
l = [NamedObject("foo bar"),NamedObject("bar bleh")]
|
||||
l = [NamedObject("foo bar"), NamedObject("bar bleh")]
|
||||
matches = getmatches(l)
|
||||
m = matches[0]
|
||||
r = get_groups(matches)
|
||||
eq_(1,len(r))
|
||||
eq_(1, len(r))
|
||||
g = r[0]
|
||||
assert g.ref is m.first
|
||||
eq_([m.second],g.dupes)
|
||||
eq_([m.second], g.dupes)
|
||||
|
||||
def test_group_with_multiple_matches(self):
|
||||
#This results in 3 matches
|
||||
l = [NamedObject("foo"),NamedObject("foo"),NamedObject("foo")]
|
||||
l = [NamedObject("foo"), NamedObject("foo"), NamedObject("foo")]
|
||||
matches = getmatches(l)
|
||||
r = get_groups(matches)
|
||||
eq_(1,len(r))
|
||||
eq_(1, len(r))
|
||||
g = r[0]
|
||||
eq_(3,len(g))
|
||||
eq_(3, len(g))
|
||||
|
||||
def test_must_choose_a_group(self):
|
||||
l = [NamedObject("a b"),NamedObject("a b"),NamedObject("b c"),NamedObject("c d"),NamedObject("c d")]
|
||||
l = [NamedObject("a b"), NamedObject("a b"), NamedObject("b c"), NamedObject("c d"), NamedObject("c d")]
|
||||
#There will be 2 groups here: group "a b" and group "c d"
|
||||
#"b c" can go either of them, but not both.
|
||||
matches = getmatches(l)
|
||||
r = get_groups(matches)
|
||||
eq_(2,len(r))
|
||||
eq_(5,len(r[0])+len(r[1]))
|
||||
eq_(2, len(r))
|
||||
eq_(5, len(r[0])+len(r[1]))
|
||||
|
||||
def test_should_all_go_in_the_same_group(self):
|
||||
l = [NamedObject("a b"),NamedObject("a b"),NamedObject("a b"),NamedObject("a b")]
|
||||
l = [NamedObject("a b"), NamedObject("a b"), NamedObject("a b"), NamedObject("a b")]
|
||||
#There will be 2 groups here: group "a b" and group "c d"
|
||||
#"b c" can fit in both, but it must be in only one of them
|
||||
matches = getmatches(l)
|
||||
r = get_groups(matches)
|
||||
eq_(1,len(r))
|
||||
eq_(1, len(r))
|
||||
|
||||
def test_give_priority_to_matches_with_higher_percentage(self):
|
||||
o1 = NamedObject(with_words=True)
|
||||
@ -775,10 +778,10 @@ class TestCaseget_groups:
|
||||
o3 = NamedObject(with_words=True)
|
||||
m1 = Match(o1, o2, 1)
|
||||
m2 = Match(o2, o3, 2)
|
||||
r = get_groups([m1,m2])
|
||||
eq_(1,len(r))
|
||||
r = get_groups([m1, m2])
|
||||
eq_(1, len(r))
|
||||
g = r[0]
|
||||
eq_(2,len(g))
|
||||
eq_(2, len(g))
|
||||
assert o1 not in g
|
||||
assert o2 in g
|
||||
assert o3 in g
|
||||
@ -787,32 +790,32 @@ class TestCaseget_groups:
|
||||
l = [NamedObject("foobar") for i in range(4)]
|
||||
m = getmatches(l)
|
||||
r = get_groups(m)
|
||||
eq_(1,len(r))
|
||||
eq_(4,len(r[0]))
|
||||
eq_(1, len(r))
|
||||
eq_(4, len(r[0]))
|
||||
|
||||
def test_referenced_by_ref2(self):
|
||||
o1 = NamedObject(with_words=True)
|
||||
o2 = NamedObject(with_words=True)
|
||||
o3 = NamedObject(with_words=True)
|
||||
m1 = get_match(o1,o2)
|
||||
m2 = get_match(o3,o1)
|
||||
m3 = get_match(o3,o2)
|
||||
r = get_groups([m1,m2,m3])
|
||||
eq_(3,len(r[0]))
|
||||
m1 = get_match(o1, o2)
|
||||
m2 = get_match(o3, o1)
|
||||
m3 = get_match(o3, o2)
|
||||
r = get_groups([m1, m2, m3])
|
||||
eq_(3, len(r[0]))
|
||||
|
||||
def test_job(self):
|
||||
def do_progress(p,d=''):
|
||||
def do_progress(p, d=''):
|
||||
self.log.append(p)
|
||||
return True
|
||||
|
||||
self.log = []
|
||||
j = job.Job(1,do_progress)
|
||||
m1,m2,m3 = get_match_triangle()
|
||||
j = job.Job(1, do_progress)
|
||||
m1, m2, m3 = get_match_triangle()
|
||||
#101%: To make sure it is processed first so the job test works correctly
|
||||
m4 = Match(NamedObject('a',True), NamedObject('a',True), 101)
|
||||
get_groups([m1,m2,m3,m4],j)
|
||||
eq_(0,self.log[0])
|
||||
eq_(100,self.log[-1])
|
||||
m4 = Match(NamedObject('a', True), NamedObject('a', True), 101)
|
||||
get_groups([m1, m2, m3, m4], j)
|
||||
eq_(0, self.log[0])
|
||||
eq_(100, self.log[-1])
|
||||
|
||||
def test_group_admissible_discarded_dupes(self):
|
||||
# If, with a (A, B, C, D) set, all match with A, but C and D don't match with B and that the
|
||||
|
@ -1,9 +1,7 @@
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2006/05/02
|
||||
# Copyright 2015 Hardcoded Software (http://www.hardcoded.net)
|
||||
#
|
||||
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# Copyright 2016 Hardcoded Software (http://www.hardcoded.net)
|
||||
#
|
||||
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
import io
|
||||
@ -12,54 +10,54 @@ from xml.etree import ElementTree as ET
|
||||
from pytest import raises
|
||||
from hscommon.testutil import eq_
|
||||
|
||||
from ..ignore import *
|
||||
from ..ignore import IgnoreList
|
||||
|
||||
def test_empty():
|
||||
il = IgnoreList()
|
||||
eq_(0,len(il))
|
||||
assert not il.AreIgnored('foo','bar')
|
||||
eq_(0, len(il))
|
||||
assert not il.AreIgnored('foo', 'bar')
|
||||
|
||||
def test_simple():
|
||||
il = IgnoreList()
|
||||
il.Ignore('foo','bar')
|
||||
assert il.AreIgnored('foo','bar')
|
||||
assert il.AreIgnored('bar','foo')
|
||||
assert not il.AreIgnored('foo','bleh')
|
||||
assert not il.AreIgnored('bleh','bar')
|
||||
eq_(1,len(il))
|
||||
il.Ignore('foo', 'bar')
|
||||
assert il.AreIgnored('foo', 'bar')
|
||||
assert il.AreIgnored('bar', 'foo')
|
||||
assert not il.AreIgnored('foo', 'bleh')
|
||||
assert not il.AreIgnored('bleh', 'bar')
|
||||
eq_(1, len(il))
|
||||
|
||||
def test_multiple():
|
||||
il = IgnoreList()
|
||||
il.Ignore('foo','bar')
|
||||
il.Ignore('foo','bleh')
|
||||
il.Ignore('bleh','bar')
|
||||
il.Ignore('aybabtu','bleh')
|
||||
assert il.AreIgnored('foo','bar')
|
||||
assert il.AreIgnored('bar','foo')
|
||||
assert il.AreIgnored('foo','bleh')
|
||||
assert il.AreIgnored('bleh','bar')
|
||||
assert not il.AreIgnored('aybabtu','bar')
|
||||
eq_(4,len(il))
|
||||
il.Ignore('foo', 'bar')
|
||||
il.Ignore('foo', 'bleh')
|
||||
il.Ignore('bleh', 'bar')
|
||||
il.Ignore('aybabtu', 'bleh')
|
||||
assert il.AreIgnored('foo', 'bar')
|
||||
assert il.AreIgnored('bar', 'foo')
|
||||
assert il.AreIgnored('foo', 'bleh')
|
||||
assert il.AreIgnored('bleh', 'bar')
|
||||
assert not il.AreIgnored('aybabtu', 'bar')
|
||||
eq_(4, len(il))
|
||||
|
||||
def test_clear():
|
||||
il = IgnoreList()
|
||||
il.Ignore('foo','bar')
|
||||
il.Ignore('foo', 'bar')
|
||||
il.Clear()
|
||||
assert not il.AreIgnored('foo','bar')
|
||||
assert not il.AreIgnored('bar','foo')
|
||||
eq_(0,len(il))
|
||||
assert not il.AreIgnored('foo', 'bar')
|
||||
assert not il.AreIgnored('bar', 'foo')
|
||||
eq_(0, len(il))
|
||||
|
||||
def test_add_same_twice():
|
||||
il = IgnoreList()
|
||||
il.Ignore('foo','bar')
|
||||
il.Ignore('bar','foo')
|
||||
eq_(1,len(il))
|
||||
il.Ignore('foo', 'bar')
|
||||
il.Ignore('bar', 'foo')
|
||||
eq_(1, len(il))
|
||||
|
||||
def test_save_to_xml():
|
||||
il = IgnoreList()
|
||||
il.Ignore('foo','bar')
|
||||
il.Ignore('foo','bleh')
|
||||
il.Ignore('bleh','bar')
|
||||
il.Ignore('foo', 'bar')
|
||||
il.Ignore('foo', 'bleh')
|
||||
il.Ignore('bleh', 'bar')
|
||||
f = io.BytesIO()
|
||||
il.save_to_xml(f)
|
||||
f.seek(0)
|
||||
@ -83,50 +81,50 @@ def test_SaveThenLoad():
|
||||
f.seek(0)
|
||||
il = IgnoreList()
|
||||
il.load_from_xml(f)
|
||||
eq_(4,len(il))
|
||||
assert il.AreIgnored('\u00e9','bar')
|
||||
|
||||
eq_(4, len(il))
|
||||
assert il.AreIgnored('\u00e9', 'bar')
|
||||
|
||||
def test_LoadXML_with_empty_file_tags():
|
||||
f = io.BytesIO()
|
||||
f.write(b'<?xml version="1.0" encoding="utf-8"?><ignore_list><file><file/></file></ignore_list>')
|
||||
f.seek(0)
|
||||
il = IgnoreList()
|
||||
il.load_from_xml(f)
|
||||
eq_(0,len(il))
|
||||
|
||||
eq_(0, len(il))
|
||||
|
||||
def test_AreIgnore_works_when_a_child_is_a_key_somewhere_else():
|
||||
il = IgnoreList()
|
||||
il.Ignore('foo','bar')
|
||||
il.Ignore('bar','baz')
|
||||
assert il.AreIgnored('bar','foo')
|
||||
il.Ignore('foo', 'bar')
|
||||
il.Ignore('bar', 'baz')
|
||||
assert il.AreIgnored('bar', 'foo')
|
||||
|
||||
|
||||
def test_no_dupes_when_a_child_is_a_key_somewhere_else():
|
||||
il = IgnoreList()
|
||||
il.Ignore('foo','bar')
|
||||
il.Ignore('bar','baz')
|
||||
il.Ignore('bar','foo')
|
||||
eq_(2,len(il))
|
||||
il.Ignore('foo', 'bar')
|
||||
il.Ignore('bar', 'baz')
|
||||
il.Ignore('bar', 'foo')
|
||||
eq_(2, len(il))
|
||||
|
||||
def test_iterate():
|
||||
#It must be possible to iterate through ignore list
|
||||
il = IgnoreList()
|
||||
expected = [('foo','bar'),('bar','baz'),('foo','baz')]
|
||||
expected = [('foo', 'bar'), ('bar', 'baz'), ('foo', 'baz')]
|
||||
for i in expected:
|
||||
il.Ignore(i[0],i[1])
|
||||
il.Ignore(i[0], i[1])
|
||||
for i in il:
|
||||
expected.remove(i) #No exception should be raised
|
||||
assert not expected #expected should be empty
|
||||
|
||||
def test_filter():
|
||||
il = IgnoreList()
|
||||
il.Ignore('foo','bar')
|
||||
il.Ignore('bar','baz')
|
||||
il.Ignore('foo','baz')
|
||||
il.Filter(lambda f,s: f == 'bar')
|
||||
eq_(1,len(il))
|
||||
assert not il.AreIgnored('foo','bar')
|
||||
assert il.AreIgnored('bar','baz')
|
||||
il.Ignore('foo', 'bar')
|
||||
il.Ignore('bar', 'baz')
|
||||
il.Ignore('foo', 'baz')
|
||||
il.Filter(lambda f, s: f == 'bar')
|
||||
eq_(1, len(il))
|
||||
assert not il.AreIgnored('foo', 'bar')
|
||||
assert il.AreIgnored('bar', 'baz')
|
||||
|
||||
def test_save_with_non_ascii_items():
|
||||
il = IgnoreList()
|
||||
@ -139,14 +137,14 @@ def test_save_with_non_ascii_items():
|
||||
|
||||
def test_len():
|
||||
il = IgnoreList()
|
||||
eq_(0,len(il))
|
||||
il.Ignore('foo','bar')
|
||||
eq_(1,len(il))
|
||||
eq_(0, len(il))
|
||||
il.Ignore('foo', 'bar')
|
||||
eq_(1, len(il))
|
||||
|
||||
def test_nonzero():
|
||||
il = IgnoreList()
|
||||
assert not il
|
||||
il.Ignore('foo','bar')
|
||||
il.Ignore('foo', 'bar')
|
||||
assert il
|
||||
|
||||
def test_remove():
|
||||
|
@ -1,14 +1,12 @@
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2006/02/23
|
||||
# Copyright 2015 Hardcoded Software (http://www.hardcoded.net)
|
||||
# Copyright 2016 Hardcoded Software (http://www.hardcoded.net)
|
||||
|
||||
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
from hscommon.testutil import eq_
|
||||
|
||||
from ..markable import *
|
||||
from ..markable import MarkableList, Markable
|
||||
|
||||
def gen():
|
||||
ml = MarkableList()
|
||||
@ -36,7 +34,7 @@ def test_unmark_unmarked():
|
||||
ml = gen()
|
||||
assert not ml.unmark(4)
|
||||
assert not ml.is_marked(4)
|
||||
|
||||
|
||||
def test_mark_twice_and_unmark():
|
||||
ml = gen()
|
||||
assert ml.mark(5)
|
||||
@ -73,6 +71,7 @@ def test_change_notifications():
|
||||
class Foobar(Markable):
|
||||
def _did_mark(self, o):
|
||||
self.log.append((True, o))
|
||||
|
||||
def _did_unmark(self, o):
|
||||
self.log.append((False, o))
|
||||
|
||||
@ -84,15 +83,15 @@ def test_change_notifications():
|
||||
f.unmark('foo')
|
||||
f.unmark('foo')
|
||||
f.mark_toggle('bar')
|
||||
eq_([(True,'foo'),(True,'bar'),(False,'foo'),(False,'bar')],f.log)
|
||||
eq_([(True, 'foo'), (True, 'bar'), (False, 'foo'), (False, 'bar')], f.log)
|
||||
|
||||
def test_mark_count():
|
||||
ml = gen()
|
||||
eq_(0,ml.mark_count)
|
||||
eq_(0, ml.mark_count)
|
||||
ml.mark(7)
|
||||
eq_(1,ml.mark_count)
|
||||
eq_(1, ml.mark_count)
|
||||
ml.mark(11)
|
||||
eq_(1,ml.mark_count)
|
||||
eq_(1, ml.mark_count)
|
||||
|
||||
def test_mark_none():
|
||||
log = []
|
||||
@ -100,16 +99,16 @@ def test_mark_none():
|
||||
ml._did_unmark = lambda o: log.append(o)
|
||||
ml.mark(1)
|
||||
ml.mark(2)
|
||||
eq_(2,ml.mark_count)
|
||||
eq_(2, ml.mark_count)
|
||||
ml.mark_none()
|
||||
eq_(0,ml.mark_count)
|
||||
eq_([1,2],log)
|
||||
eq_(0, ml.mark_count)
|
||||
eq_([1, 2], log)
|
||||
|
||||
def test_mark_all():
|
||||
ml = gen()
|
||||
eq_(0,ml.mark_count)
|
||||
eq_(0, ml.mark_count)
|
||||
ml.mark_all()
|
||||
eq_(10,ml.mark_count)
|
||||
eq_(10, ml.mark_count)
|
||||
assert ml.is_marked(1)
|
||||
|
||||
def test_mark_invert():
|
||||
@ -122,8 +121,8 @@ def test_mark_invert():
|
||||
def test_mark_while_inverted():
|
||||
log = []
|
||||
ml = gen()
|
||||
ml._did_unmark = lambda o:log.append((False,o))
|
||||
ml._did_mark = lambda o:log.append((True,o))
|
||||
ml._did_unmark = lambda o: log.append((False, o))
|
||||
ml._did_mark = lambda o: log.append((True, o))
|
||||
ml.mark(1)
|
||||
ml.mark_invert()
|
||||
assert ml.mark_inverted
|
||||
@ -132,9 +131,9 @@ def test_mark_while_inverted():
|
||||
assert ml.unmark(1)
|
||||
ml.mark_toggle(3)
|
||||
assert not ml.is_marked(3)
|
||||
eq_(7,ml.mark_count)
|
||||
eq_([(True,1),(False,1),(True,2),(True,1),(True,3)],log)
|
||||
|
||||
eq_(7, ml.mark_count)
|
||||
eq_([(True, 1), (False, 1), (True, 2), (True, 1), (True, 3)], log)
|
||||
|
||||
def test_remove_mark_flag():
|
||||
ml = gen()
|
||||
ml.mark(1)
|
||||
@ -145,7 +144,7 @@ def test_remove_mark_flag():
|
||||
assert not ml.is_marked(1)
|
||||
ml._remove_mark_flag(1)
|
||||
assert ml.is_marked(1)
|
||||
|
||||
|
||||
def test_is_marked_returns_false_if_object_not_markable():
|
||||
class MyMarkableList(MarkableList):
|
||||
def _is_markable(self, o):
|
||||
|
@ -1,9 +1,7 @@
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2006/02/23
|
||||
# Copyright 2015 Hardcoded Software (http://www.hardcoded.net)
|
||||
#
|
||||
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# Copyright 2016 Hardcoded Software (http://www.hardcoded.net)
|
||||
#
|
||||
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
import io
|
||||
@ -22,21 +20,21 @@ class TestCaseResultsEmpty:
|
||||
def setup_method(self, method):
|
||||
self.app = DupeGuru()
|
||||
self.results = self.app.results
|
||||
|
||||
|
||||
def test_apply_invalid_filter(self):
|
||||
# If the applied filter is an invalid regexp, just ignore the filter.
|
||||
self.results.apply_filter('[') # invalid
|
||||
self.test_stat_line() # make sure that the stats line isn't saying we applied a '[' filter
|
||||
|
||||
|
||||
def test_stat_line(self):
|
||||
eq_("0 / 0 (0.00 B / 0.00 B) duplicates marked.",self.results.stat_line)
|
||||
|
||||
eq_("0 / 0 (0.00 B / 0.00 B) duplicates marked.", self.results.stat_line)
|
||||
|
||||
def test_groups(self):
|
||||
eq_(0,len(self.results.groups))
|
||||
|
||||
eq_(0, len(self.results.groups))
|
||||
|
||||
def test_get_group_of_duplicate(self):
|
||||
assert self.results.get_group_of_duplicate('foo') is None
|
||||
|
||||
|
||||
def test_save_to_xml(self):
|
||||
f = io.BytesIO()
|
||||
self.results.save_to_xml(f)
|
||||
@ -44,15 +42,15 @@ class TestCaseResultsEmpty:
|
||||
doc = ET.parse(f)
|
||||
root = doc.getroot()
|
||||
eq_('results', root.tag)
|
||||
|
||||
|
||||
def test_is_modified(self):
|
||||
assert not self.results.is_modified
|
||||
|
||||
|
||||
def test_is_modified_after_setting_empty_group(self):
|
||||
# Don't consider results as modified if they're empty
|
||||
self.results.groups = []
|
||||
assert not self.results.is_modified
|
||||
|
||||
|
||||
def test_save_to_same_name_as_folder(self, tmpdir):
|
||||
# Issue #149
|
||||
# When saving to a filename that already exists, the file is overwritten. However, when
|
||||
@ -64,108 +62,108 @@ class TestCaseResultsEmpty:
|
||||
folderpath.mkdir()
|
||||
self.results.save_to_xml(str(folderpath)) # no crash
|
||||
assert tmpdir.join('[000] foo').check()
|
||||
|
||||
|
||||
|
||||
class TestCaseResultsWithSomeGroups:
|
||||
def setup_method(self, method):
|
||||
self.app = DupeGuru()
|
||||
self.results = self.app.results
|
||||
self.objects,self.matches,self.groups = GetTestGroups()
|
||||
self.objects, self.matches, self.groups = GetTestGroups()
|
||||
self.results.groups = self.groups
|
||||
|
||||
|
||||
def test_stat_line(self):
|
||||
eq_("0 / 3 (0.00 B / 1.01 KB) duplicates marked.",self.results.stat_line)
|
||||
|
||||
eq_("0 / 3 (0.00 B / 1.01 KB) duplicates marked.", self.results.stat_line)
|
||||
|
||||
def test_groups(self):
|
||||
eq_(2,len(self.results.groups))
|
||||
|
||||
eq_(2, len(self.results.groups))
|
||||
|
||||
def test_get_group_of_duplicate(self):
|
||||
for o in self.objects:
|
||||
g = self.results.get_group_of_duplicate(o)
|
||||
assert isinstance(g, engine.Group)
|
||||
assert o in g
|
||||
assert self.results.get_group_of_duplicate(self.groups[0]) is None
|
||||
|
||||
|
||||
def test_remove_duplicates(self):
|
||||
g1,g2 = self.results.groups
|
||||
g1, g2 = self.results.groups
|
||||
self.results.remove_duplicates([g1.dupes[0]])
|
||||
eq_(2,len(g1))
|
||||
eq_(2, len(g1))
|
||||
assert g1 in self.results.groups
|
||||
self.results.remove_duplicates([g1.ref])
|
||||
eq_(2,len(g1))
|
||||
eq_(2, len(g1))
|
||||
assert g1 in self.results.groups
|
||||
self.results.remove_duplicates([g1.dupes[0]])
|
||||
eq_(0,len(g1))
|
||||
eq_(0, len(g1))
|
||||
assert g1 not in self.results.groups
|
||||
self.results.remove_duplicates([g2.dupes[0]])
|
||||
eq_(0,len(g2))
|
||||
eq_(0, len(g2))
|
||||
assert g2 not in self.results.groups
|
||||
eq_(0,len(self.results.groups))
|
||||
|
||||
eq_(0, len(self.results.groups))
|
||||
|
||||
def test_remove_duplicates_with_ref_files(self):
|
||||
g1,g2 = self.results.groups
|
||||
g1, g2 = self.results.groups
|
||||
self.objects[0].is_ref = True
|
||||
self.objects[1].is_ref = True
|
||||
self.results.remove_duplicates([self.objects[2]])
|
||||
eq_(0,len(g1))
|
||||
eq_(0, len(g1))
|
||||
assert g1 not in self.results.groups
|
||||
|
||||
|
||||
def test_make_ref(self):
|
||||
g = self.results.groups[0]
|
||||
d = g.dupes[0]
|
||||
self.results.make_ref(d)
|
||||
assert d is g.ref
|
||||
|
||||
|
||||
def test_sort_groups(self):
|
||||
self.results.make_ref(self.objects[1]) #We want to make the 1024 sized object to go ref.
|
||||
g1,g2 = self.groups
|
||||
g1, g2 = self.groups
|
||||
self.results.sort_groups('size')
|
||||
assert self.results.groups[0] is g2
|
||||
assert self.results.groups[1] is g1
|
||||
self.results.sort_groups('size', False)
|
||||
assert self.results.groups[0] is g1
|
||||
assert self.results.groups[1] is g2
|
||||
|
||||
|
||||
def test_set_groups_when_sorted(self):
|
||||
self.results.make_ref(self.objects[1]) #We want to make the 1024 sized object to go ref.
|
||||
self.results.sort_groups('size')
|
||||
objects,matches,groups = GetTestGroups()
|
||||
g1,g2 = groups
|
||||
objects, matches, groups = GetTestGroups()
|
||||
g1, g2 = groups
|
||||
g1.switch_ref(objects[1])
|
||||
self.results.groups = groups
|
||||
assert self.results.groups[0] is g2
|
||||
assert self.results.groups[1] is g1
|
||||
|
||||
|
||||
def test_get_dupe_list(self):
|
||||
eq_([self.objects[1],self.objects[2],self.objects[4]],self.results.dupes)
|
||||
|
||||
eq_([self.objects[1], self.objects[2], self.objects[4]], self.results.dupes)
|
||||
|
||||
def test_dupe_list_is_cached(self):
|
||||
assert self.results.dupes is self.results.dupes
|
||||
|
||||
|
||||
def test_dupe_list_cache_is_invalidated_when_needed(self):
|
||||
o1,o2,o3,o4,o5 = self.objects
|
||||
eq_([o2,o3,o5],self.results.dupes)
|
||||
o1, o2, o3, o4, o5 = self.objects
|
||||
eq_([o2, o3, o5], self.results.dupes)
|
||||
self.results.make_ref(o2)
|
||||
eq_([o1,o3,o5],self.results.dupes)
|
||||
objects,matches,groups = GetTestGroups()
|
||||
o1,o2,o3,o4,o5 = objects
|
||||
eq_([o1, o3, o5], self.results.dupes)
|
||||
objects, matches, groups = GetTestGroups()
|
||||
o1, o2, o3, o4, o5 = objects
|
||||
self.results.groups = groups
|
||||
eq_([o2,o3,o5],self.results.dupes)
|
||||
|
||||
eq_([o2, o3, o5], self.results.dupes)
|
||||
|
||||
def test_dupe_list_sort(self):
|
||||
o1,o2,o3,o4,o5 = self.objects
|
||||
o1, o2, o3, o4, o5 = self.objects
|
||||
o1.size = 5
|
||||
o2.size = 4
|
||||
o3.size = 3
|
||||
o4.size = 2
|
||||
o5.size = 1
|
||||
self.results.sort_dupes('size')
|
||||
eq_([o5,o3,o2],self.results.dupes)
|
||||
eq_([o5, o3, o2], self.results.dupes)
|
||||
self.results.sort_dupes('size', False)
|
||||
eq_([o2,o3,o5],self.results.dupes)
|
||||
|
||||
eq_([o2, o3, o5], self.results.dupes)
|
||||
|
||||
def test_dupe_list_remember_sort(self):
|
||||
o1,o2,o3,o4,o5 = self.objects
|
||||
o1, o2, o3, o4, o5 = self.objects
|
||||
o1.size = 5
|
||||
o2.size = 4
|
||||
o3.size = 3
|
||||
@ -173,40 +171,40 @@ class TestCaseResultsWithSomeGroups:
|
||||
o5.size = 1
|
||||
self.results.sort_dupes('size')
|
||||
self.results.make_ref(o2)
|
||||
eq_([o5,o3,o1],self.results.dupes)
|
||||
|
||||
eq_([o5, o3, o1], self.results.dupes)
|
||||
|
||||
def test_dupe_list_sort_delta_values(self):
|
||||
o1,o2,o3,o4,o5 = self.objects
|
||||
o1, o2, o3, o4, o5 = self.objects
|
||||
o1.size = 10
|
||||
o2.size = 2 #-8
|
||||
o3.size = 3 #-7
|
||||
o4.size = 20
|
||||
o5.size = 1 #-19
|
||||
self.results.sort_dupes('size', delta=True)
|
||||
eq_([o5,o2,o3],self.results.dupes)
|
||||
|
||||
eq_([o5, o2, o3], self.results.dupes)
|
||||
|
||||
def test_sort_empty_list(self):
|
||||
#There was an infinite loop when sorting an empty list.
|
||||
app = DupeGuru()
|
||||
r = app.results
|
||||
r.sort_dupes('name')
|
||||
eq_([],r.dupes)
|
||||
|
||||
eq_([], r.dupes)
|
||||
|
||||
def test_dupe_list_update_on_remove_duplicates(self):
|
||||
o1,o2,o3,o4,o5 = self.objects
|
||||
eq_(3,len(self.results.dupes))
|
||||
o1, o2, o3, o4, o5 = self.objects
|
||||
eq_(3, len(self.results.dupes))
|
||||
self.results.remove_duplicates([o2])
|
||||
eq_(2,len(self.results.dupes))
|
||||
|
||||
eq_(2, len(self.results.dupes))
|
||||
|
||||
def test_is_modified(self):
|
||||
# Changing the groups sets the modified flag
|
||||
assert self.results.is_modified
|
||||
|
||||
|
||||
def test_is_modified_after_save_and_load(self):
|
||||
# Saving/Loading a file sets the modified flag back to False
|
||||
def get_file(path):
|
||||
return [f for f in self.objects if str(f.path) == path][0]
|
||||
|
||||
|
||||
f = io.BytesIO()
|
||||
self.results.save_to_xml(f)
|
||||
assert not self.results.is_modified
|
||||
@ -214,13 +212,13 @@ class TestCaseResultsWithSomeGroups:
|
||||
f.seek(0)
|
||||
self.results.load_from_xml(f, get_file)
|
||||
assert not self.results.is_modified
|
||||
|
||||
|
||||
def test_is_modified_after_removing_all_results(self):
|
||||
# Removing all results sets the is_modified flag to false.
|
||||
self.results.mark_all()
|
||||
self.results.perform_on_marked(lambda x:None, True)
|
||||
self.results.perform_on_marked(lambda x: None, True)
|
||||
assert not self.results.is_modified
|
||||
|
||||
|
||||
def test_group_of_duplicate_after_removal(self):
|
||||
# removing a duplicate also removes it from the dupe:group map.
|
||||
dupe = self.results.groups[1].dupes[0]
|
||||
@ -229,7 +227,7 @@ class TestCaseResultsWithSomeGroups:
|
||||
assert self.results.get_group_of_duplicate(dupe) is None
|
||||
# also remove group ref
|
||||
assert self.results.get_group_of_duplicate(ref) is None
|
||||
|
||||
|
||||
def test_dupe_list_sort_delta_values_nonnumeric(self):
|
||||
# When sorting dupes in delta mode on a non-numeric column, our first sort criteria is if
|
||||
# the string is the same as its ref.
|
||||
@ -239,7 +237,7 @@ class TestCaseResultsWithSomeGroups:
|
||||
g2r.name = g2d1.name = "aaa"
|
||||
self.results.sort_dupes('name', delta=True)
|
||||
eq_("aaa", self.results.dupes[2].name)
|
||||
|
||||
|
||||
def test_dupe_list_sort_delta_values_nonnumeric_case_insensitive(self):
|
||||
# Non-numeric delta sorting comparison is case insensitive
|
||||
g1r, g1d1, g1d2, g2r, g2d1 = self.objects
|
||||
@ -252,92 +250,92 @@ class TestCaseResultsWithSavedResults:
|
||||
def setup_method(self, method):
|
||||
self.app = DupeGuru()
|
||||
self.results = self.app.results
|
||||
self.objects,self.matches,self.groups = GetTestGroups()
|
||||
self.objects, self.matches, self.groups = GetTestGroups()
|
||||
self.results.groups = self.groups
|
||||
self.f = io.BytesIO()
|
||||
self.results.save_to_xml(self.f)
|
||||
self.f.seek(0)
|
||||
|
||||
|
||||
def test_is_modified(self):
|
||||
# Saving a file sets the modified flag back to False
|
||||
assert not self.results.is_modified
|
||||
|
||||
|
||||
def test_is_modified_after_load(self):
|
||||
# Loading a file sets the modified flag back to False
|
||||
def get_file(path):
|
||||
return [f for f in self.objects if str(f.path) == path][0]
|
||||
|
||||
|
||||
self.results.groups = self.groups # sets the flag back
|
||||
self.results.load_from_xml(self.f, get_file)
|
||||
assert not self.results.is_modified
|
||||
|
||||
|
||||
def test_is_modified_after_remove(self):
|
||||
# Removing dupes sets the modified flag
|
||||
self.results.remove_duplicates([self.results.groups[0].dupes[0]])
|
||||
assert self.results.is_modified
|
||||
|
||||
|
||||
def test_is_modified_after_make_ref(self):
|
||||
# Making a dupe ref sets the modified flag
|
||||
self.results.make_ref(self.results.groups[0].dupes[0])
|
||||
assert self.results.is_modified
|
||||
|
||||
|
||||
|
||||
class TestCaseResultsMarkings:
|
||||
def setup_method(self, method):
|
||||
self.app = DupeGuru()
|
||||
self.results = self.app.results
|
||||
self.objects,self.matches,self.groups = GetTestGroups()
|
||||
self.objects, self.matches, self.groups = GetTestGroups()
|
||||
self.results.groups = self.groups
|
||||
|
||||
|
||||
def test_stat_line(self):
|
||||
eq_("0 / 3 (0.00 B / 1.01 KB) duplicates marked.",self.results.stat_line)
|
||||
eq_("0 / 3 (0.00 B / 1.01 KB) duplicates marked.", self.results.stat_line)
|
||||
self.results.mark(self.objects[1])
|
||||
eq_("1 / 3 (1.00 KB / 1.01 KB) duplicates marked.",self.results.stat_line)
|
||||
eq_("1 / 3 (1.00 KB / 1.01 KB) duplicates marked.", self.results.stat_line)
|
||||
self.results.mark_invert()
|
||||
eq_("2 / 3 (2.00 B / 1.01 KB) duplicates marked.",self.results.stat_line)
|
||||
eq_("2 / 3 (2.00 B / 1.01 KB) duplicates marked.", self.results.stat_line)
|
||||
self.results.mark_invert()
|
||||
self.results.unmark(self.objects[1])
|
||||
self.results.mark(self.objects[2])
|
||||
self.results.mark(self.objects[4])
|
||||
eq_("2 / 3 (2.00 B / 1.01 KB) duplicates marked.",self.results.stat_line)
|
||||
eq_("2 / 3 (2.00 B / 1.01 KB) duplicates marked.", self.results.stat_line)
|
||||
self.results.mark(self.objects[0]) #this is a ref, it can't be counted
|
||||
eq_("2 / 3 (2.00 B / 1.01 KB) duplicates marked.",self.results.stat_line)
|
||||
eq_("2 / 3 (2.00 B / 1.01 KB) duplicates marked.", self.results.stat_line)
|
||||
self.results.groups = self.groups
|
||||
eq_("0 / 3 (0.00 B / 1.01 KB) duplicates marked.",self.results.stat_line)
|
||||
|
||||
eq_("0 / 3 (0.00 B / 1.01 KB) duplicates marked.", self.results.stat_line)
|
||||
|
||||
def test_with_ref_duplicate(self):
|
||||
self.objects[1].is_ref = True
|
||||
self.results.groups = self.groups
|
||||
assert not self.results.mark(self.objects[1])
|
||||
self.results.mark(self.objects[2])
|
||||
eq_("1 / 2 (1.00 B / 2.00 B) duplicates marked.",self.results.stat_line)
|
||||
|
||||
eq_("1 / 2 (1.00 B / 2.00 B) duplicates marked.", self.results.stat_line)
|
||||
|
||||
def test_perform_on_marked(self):
|
||||
def log_object(o):
|
||||
log.append(o)
|
||||
return True
|
||||
|
||||
|
||||
log = []
|
||||
self.results.mark_all()
|
||||
self.results.perform_on_marked(log_object,False)
|
||||
self.results.perform_on_marked(log_object, False)
|
||||
assert self.objects[1] in log
|
||||
assert self.objects[2] in log
|
||||
assert self.objects[4] in log
|
||||
eq_(3,len(log))
|
||||
eq_(3, len(log))
|
||||
log = []
|
||||
self.results.mark_none()
|
||||
self.results.mark(self.objects[4])
|
||||
self.results.perform_on_marked(log_object,True)
|
||||
eq_(1,len(log))
|
||||
self.results.perform_on_marked(log_object, True)
|
||||
eq_(1, len(log))
|
||||
assert self.objects[4] in log
|
||||
eq_(1,len(self.results.groups))
|
||||
|
||||
eq_(1, len(self.results.groups))
|
||||
|
||||
def test_perform_on_marked_with_problems(self):
|
||||
def log_object(o):
|
||||
log.append(o)
|
||||
if o is self.objects[1]:
|
||||
raise EnvironmentError('foobar')
|
||||
|
||||
|
||||
log = []
|
||||
self.results.mark_all()
|
||||
assert self.results.is_marked(self.objects[1])
|
||||
@ -352,55 +350,55 @@ class TestCaseResultsMarkings:
|
||||
dupe, msg = self.results.problems[0]
|
||||
assert dupe is self.objects[1]
|
||||
eq_(msg, 'foobar')
|
||||
|
||||
|
||||
def test_perform_on_marked_with_ref(self):
|
||||
def log_object(o):
|
||||
log.append(o)
|
||||
return True
|
||||
|
||||
|
||||
log = []
|
||||
self.objects[0].is_ref = True
|
||||
self.objects[1].is_ref = True
|
||||
self.results.mark_all()
|
||||
self.results.perform_on_marked(log_object,True)
|
||||
self.results.perform_on_marked(log_object, True)
|
||||
assert self.objects[1] not in log
|
||||
assert self.objects[2] in log
|
||||
assert self.objects[4] in log
|
||||
eq_(2,len(log))
|
||||
eq_(0,len(self.results.groups))
|
||||
|
||||
eq_(2, len(log))
|
||||
eq_(0, len(self.results.groups))
|
||||
|
||||
def test_perform_on_marked_remove_objects_only_at_the_end(self):
|
||||
def check_groups(o):
|
||||
eq_(3,len(g1))
|
||||
eq_(2,len(g2))
|
||||
eq_(3, len(g1))
|
||||
eq_(2, len(g2))
|
||||
return True
|
||||
|
||||
g1,g2 = self.results.groups
|
||||
|
||||
g1, g2 = self.results.groups
|
||||
self.results.mark_all()
|
||||
self.results.perform_on_marked(check_groups,True)
|
||||
eq_(0,len(g1))
|
||||
eq_(0,len(g2))
|
||||
eq_(0,len(self.results.groups))
|
||||
|
||||
self.results.perform_on_marked(check_groups, True)
|
||||
eq_(0, len(g1))
|
||||
eq_(0, len(g2))
|
||||
eq_(0, len(self.results.groups))
|
||||
|
||||
def test_remove_duplicates(self):
|
||||
g1 = self.results.groups[0]
|
||||
self.results.mark(g1.dupes[0])
|
||||
eq_("1 / 3 (1.00 KB / 1.01 KB) duplicates marked.",self.results.stat_line)
|
||||
eq_("1 / 3 (1.00 KB / 1.01 KB) duplicates marked.", self.results.stat_line)
|
||||
self.results.remove_duplicates([g1.dupes[1]])
|
||||
eq_("1 / 2 (1.00 KB / 1.01 KB) duplicates marked.",self.results.stat_line)
|
||||
eq_("1 / 2 (1.00 KB / 1.01 KB) duplicates marked.", self.results.stat_line)
|
||||
self.results.remove_duplicates([g1.dupes[0]])
|
||||
eq_("0 / 1 (0.00 B / 1.00 B) duplicates marked.",self.results.stat_line)
|
||||
|
||||
eq_("0 / 1 (0.00 B / 1.00 B) duplicates marked.", self.results.stat_line)
|
||||
|
||||
def test_make_ref(self):
|
||||
g = self.results.groups[0]
|
||||
d = g.dupes[0]
|
||||
self.results.mark(d)
|
||||
eq_("1 / 3 (1.00 KB / 1.01 KB) duplicates marked.",self.results.stat_line)
|
||||
eq_("1 / 3 (1.00 KB / 1.01 KB) duplicates marked.", self.results.stat_line)
|
||||
self.results.make_ref(d)
|
||||
eq_("0 / 3 (0.00 B / 3.00 B) duplicates marked.",self.results.stat_line)
|
||||
eq_("0 / 3 (0.00 B / 3.00 B) duplicates marked.", self.results.stat_line)
|
||||
self.results.make_ref(d)
|
||||
eq_("0 / 3 (0.00 B / 3.00 B) duplicates marked.",self.results.stat_line)
|
||||
|
||||
eq_("0 / 3 (0.00 B / 3.00 B) duplicates marked.", self.results.stat_line)
|
||||
|
||||
def test_SaveXML(self):
|
||||
self.results.mark(self.objects[1])
|
||||
self.results.mark_invert()
|
||||
@ -417,11 +415,11 @@ class TestCaseResultsMarkings:
|
||||
d1, d2 = g2.getiterator('file')
|
||||
eq_('n', d1.get('marked'))
|
||||
eq_('y', d2.get('marked'))
|
||||
|
||||
|
||||
def test_LoadXML(self):
|
||||
def get_file(path):
|
||||
return [f for f in self.objects if str(f.path) == path][0]
|
||||
|
||||
|
||||
self.objects[4].name = 'ibabtu 2' #we can't have 2 files with the same path
|
||||
self.results.mark(self.objects[1])
|
||||
self.results.mark_invert()
|
||||
@ -430,13 +428,13 @@ class TestCaseResultsMarkings:
|
||||
f.seek(0)
|
||||
app = DupeGuru()
|
||||
r = Results(app)
|
||||
r.load_from_xml(f,get_file)
|
||||
r.load_from_xml(f, get_file)
|
||||
assert not r.is_marked(self.objects[0])
|
||||
assert not r.is_marked(self.objects[1])
|
||||
assert r.is_marked(self.objects[2])
|
||||
assert not r.is_marked(self.objects[3])
|
||||
assert r.is_marked(self.objects[4])
|
||||
|
||||
|
||||
|
||||
class TestCaseResultsXML:
|
||||
def setup_method(self, method):
|
||||
@ -444,13 +442,13 @@ class TestCaseResultsXML:
|
||||
self.results = self.app.results
|
||||
self.objects, self.matches, self.groups = GetTestGroups()
|
||||
self.results.groups = self.groups
|
||||
|
||||
|
||||
def get_file(self, path): # use this as a callback for load_from_xml
|
||||
return [o for o in self.objects if o.path == path][0]
|
||||
|
||||
|
||||
def test_save_to_xml(self):
|
||||
self.objects[0].is_ref = True
|
||||
self.objects[0].words = [['foo','bar']]
|
||||
self.objects[0].words = [['foo', 'bar']]
|
||||
f = io.BytesIO()
|
||||
self.results.save_to_xml(f)
|
||||
f.seek(0)
|
||||
@ -460,34 +458,34 @@ class TestCaseResultsXML:
|
||||
eq_(2, len(root))
|
||||
eq_(2, len([c for c in root if c.tag == 'group']))
|
||||
g1, g2 = root
|
||||
eq_(6,len(g1))
|
||||
eq_(3,len([c for c in g1 if c.tag == 'file']))
|
||||
eq_(3,len([c for c in g1 if c.tag == 'match']))
|
||||
eq_(6, len(g1))
|
||||
eq_(3, len([c for c in g1 if c.tag == 'file']))
|
||||
eq_(3, len([c for c in g1 if c.tag == 'match']))
|
||||
d1, d2, d3 = [c for c in g1 if c.tag == 'file']
|
||||
eq_(op.join('basepath','foo bar'),d1.get('path'))
|
||||
eq_(op.join('basepath','bar bleh'),d2.get('path'))
|
||||
eq_(op.join('basepath','foo bleh'),d3.get('path'))
|
||||
eq_('y',d1.get('is_ref'))
|
||||
eq_('n',d2.get('is_ref'))
|
||||
eq_('n',d3.get('is_ref'))
|
||||
eq_('foo,bar',d1.get('words'))
|
||||
eq_('bar,bleh',d2.get('words'))
|
||||
eq_('foo,bleh',d3.get('words'))
|
||||
eq_(3,len(g2))
|
||||
eq_(2,len([c for c in g2 if c.tag == 'file']))
|
||||
eq_(1,len([c for c in g2 if c.tag == 'match']))
|
||||
eq_(op.join('basepath', 'foo bar'), d1.get('path'))
|
||||
eq_(op.join('basepath', 'bar bleh'), d2.get('path'))
|
||||
eq_(op.join('basepath', 'foo bleh'), d3.get('path'))
|
||||
eq_('y', d1.get('is_ref'))
|
||||
eq_('n', d2.get('is_ref'))
|
||||
eq_('n', d3.get('is_ref'))
|
||||
eq_('foo,bar', d1.get('words'))
|
||||
eq_('bar,bleh', d2.get('words'))
|
||||
eq_('foo,bleh', d3.get('words'))
|
||||
eq_(3, len(g2))
|
||||
eq_(2, len([c for c in g2 if c.tag == 'file']))
|
||||
eq_(1, len([c for c in g2 if c.tag == 'match']))
|
||||
d1, d2 = [c for c in g2 if c.tag == 'file']
|
||||
eq_(op.join('basepath','ibabtu'),d1.get('path'))
|
||||
eq_(op.join('basepath','ibabtu'),d2.get('path'))
|
||||
eq_('n',d1.get('is_ref'))
|
||||
eq_('n',d2.get('is_ref'))
|
||||
eq_('ibabtu',d1.get('words'))
|
||||
eq_('ibabtu',d2.get('words'))
|
||||
|
||||
eq_(op.join('basepath', 'ibabtu'), d1.get('path'))
|
||||
eq_(op.join('basepath', 'ibabtu'), d2.get('path'))
|
||||
eq_('n', d1.get('is_ref'))
|
||||
eq_('n', d2.get('is_ref'))
|
||||
eq_('ibabtu', d1.get('words'))
|
||||
eq_('ibabtu', d2.get('words'))
|
||||
|
||||
def test_LoadXML(self):
|
||||
def get_file(path):
|
||||
return [f for f in self.objects if str(f.path) == path][0]
|
||||
|
||||
|
||||
self.objects[0].is_ref = True
|
||||
self.objects[4].name = 'ibabtu 2' #we can't have 2 files with the same path
|
||||
f = io.BytesIO()
|
||||
@ -495,76 +493,76 @@ class TestCaseResultsXML:
|
||||
f.seek(0)
|
||||
app = DupeGuru()
|
||||
r = Results(app)
|
||||
r.load_from_xml(f,get_file)
|
||||
eq_(2,len(r.groups))
|
||||
g1,g2 = r.groups
|
||||
eq_(3,len(g1))
|
||||
r.load_from_xml(f, get_file)
|
||||
eq_(2, len(r.groups))
|
||||
g1, g2 = r.groups
|
||||
eq_(3, len(g1))
|
||||
assert g1[0].is_ref
|
||||
assert not g1[1].is_ref
|
||||
assert not g1[2].is_ref
|
||||
assert g1[0] is self.objects[0]
|
||||
assert g1[1] is self.objects[1]
|
||||
assert g1[2] is self.objects[2]
|
||||
eq_(['foo','bar'],g1[0].words)
|
||||
eq_(['bar','bleh'],g1[1].words)
|
||||
eq_(['foo','bleh'],g1[2].words)
|
||||
eq_(2,len(g2))
|
||||
eq_(['foo', 'bar'], g1[0].words)
|
||||
eq_(['bar', 'bleh'], g1[1].words)
|
||||
eq_(['foo', 'bleh'], g1[2].words)
|
||||
eq_(2, len(g2))
|
||||
assert not g2[0].is_ref
|
||||
assert not g2[1].is_ref
|
||||
assert g2[0] is self.objects[3]
|
||||
assert g2[1] is self.objects[4]
|
||||
eq_(['ibabtu'],g2[0].words)
|
||||
eq_(['ibabtu'],g2[1].words)
|
||||
|
||||
eq_(['ibabtu'], g2[0].words)
|
||||
eq_(['ibabtu'], g2[1].words)
|
||||
|
||||
def test_LoadXML_with_filename(self, tmpdir):
|
||||
def get_file(path):
|
||||
return [f for f in self.objects if str(f.path) == path][0]
|
||||
|
||||
|
||||
filename = str(tmpdir.join('dupeguru_results.xml'))
|
||||
self.objects[4].name = 'ibabtu 2' #we can't have 2 files with the same path
|
||||
self.results.save_to_xml(filename)
|
||||
app = DupeGuru()
|
||||
r = Results(app)
|
||||
r.load_from_xml(filename,get_file)
|
||||
eq_(2,len(r.groups))
|
||||
|
||||
r.load_from_xml(filename, get_file)
|
||||
eq_(2, len(r.groups))
|
||||
|
||||
def test_LoadXML_with_some_files_that_dont_exist_anymore(self):
|
||||
def get_file(path):
|
||||
if path.endswith('ibabtu 2'):
|
||||
return None
|
||||
return [f for f in self.objects if str(f.path) == path][0]
|
||||
|
||||
|
||||
self.objects[4].name = 'ibabtu 2' #we can't have 2 files with the same path
|
||||
f = io.BytesIO()
|
||||
self.results.save_to_xml(f)
|
||||
f.seek(0)
|
||||
app = DupeGuru()
|
||||
r = Results(app)
|
||||
r.load_from_xml(f,get_file)
|
||||
eq_(1,len(r.groups))
|
||||
eq_(3,len(r.groups[0]))
|
||||
|
||||
r.load_from_xml(f, get_file)
|
||||
eq_(1, len(r.groups))
|
||||
eq_(3, len(r.groups[0]))
|
||||
|
||||
def test_LoadXML_missing_attributes_and_bogus_elements(self):
|
||||
def get_file(path):
|
||||
return [f for f in self.objects if str(f.path) == path][0]
|
||||
|
||||
|
||||
root = ET.Element('foobar') #The root element shouldn't matter, really.
|
||||
group_node = ET.SubElement(root, 'group')
|
||||
dupe_node = ET.SubElement(group_node, 'file') #Perfectly correct file
|
||||
dupe_node.set('path', op.join('basepath','foo bar'))
|
||||
dupe_node.set('path', op.join('basepath', 'foo bar'))
|
||||
dupe_node.set('is_ref', 'y')
|
||||
dupe_node.set('words', 'foo,bar')
|
||||
dupe_node.set('words', 'foo, bar')
|
||||
dupe_node = ET.SubElement(group_node, 'file') #is_ref missing, default to 'n'
|
||||
dupe_node.set('path',op.join('basepath','foo bleh'))
|
||||
dupe_node.set('words','foo,bleh')
|
||||
dupe_node.set('path', op.join('basepath', 'foo bleh'))
|
||||
dupe_node.set('words', 'foo, bleh')
|
||||
dupe_node = ET.SubElement(group_node, 'file') #words are missing, valid.
|
||||
dupe_node.set('path',op.join('basepath','bar bleh'))
|
||||
dupe_node.set('path', op.join('basepath', 'bar bleh'))
|
||||
dupe_node = ET.SubElement(group_node, 'file') #path is missing, invalid.
|
||||
dupe_node.set('words','foo,bleh')
|
||||
dupe_node.set('words', 'foo, bleh')
|
||||
dupe_node = ET.SubElement(group_node, 'foobar') #Invalid element name
|
||||
dupe_node.set('path',op.join('basepath','bar bleh'))
|
||||
dupe_node.set('is_ref','y')
|
||||
dupe_node.set('words','bar,bleh')
|
||||
dupe_node.set('path', op.join('basepath', 'bar bleh'))
|
||||
dupe_node.set('is_ref', 'y')
|
||||
dupe_node.set('words', 'bar, bleh')
|
||||
match_node = ET.SubElement(group_node, 'match') # match pointing to a bad index
|
||||
match_node.set('first', '42')
|
||||
match_node.set('second', '45')
|
||||
@ -582,21 +580,21 @@ class TestCaseResultsXML:
|
||||
app = DupeGuru()
|
||||
r = Results(app)
|
||||
r.load_from_xml(f, get_file)
|
||||
eq_(1,len(r.groups))
|
||||
eq_(3,len(r.groups[0]))
|
||||
|
||||
eq_(1, len(r.groups))
|
||||
eq_(3, len(r.groups[0]))
|
||||
|
||||
def test_xml_non_ascii(self):
|
||||
def get_file(path):
|
||||
if path == op.join('basepath','\xe9foo bar'):
|
||||
if path == op.join('basepath', '\xe9foo bar'):
|
||||
return objects[0]
|
||||
if path == op.join('basepath','bar bleh'):
|
||||
if path == op.join('basepath', 'bar bleh'):
|
||||
return objects[1]
|
||||
|
||||
objects = [NamedObject("\xe9foo bar",True),NamedObject("bar bleh",True)]
|
||||
|
||||
objects = [NamedObject("\xe9foo bar", True), NamedObject("bar bleh", True)]
|
||||
matches = engine.getmatches(objects) #we should have 5 matches
|
||||
groups = engine.get_groups(matches) #We should have 2 groups
|
||||
for g in groups:
|
||||
g.prioritize(lambda x:objects.index(x)) #We want the dupes to be in the same order as the list is
|
||||
g.prioritize(lambda x: objects.index(x)) #We want the dupes to be in the same order as the list is
|
||||
app = DupeGuru()
|
||||
results = Results(app)
|
||||
results.groups = groups
|
||||
@ -605,20 +603,20 @@ class TestCaseResultsXML:
|
||||
f.seek(0)
|
||||
app = DupeGuru()
|
||||
r = Results(app)
|
||||
r.load_from_xml(f,get_file)
|
||||
r.load_from_xml(f, get_file)
|
||||
g = r.groups[0]
|
||||
eq_("\xe9foo bar",g[0].name)
|
||||
eq_(['efoo','bar'],g[0].words)
|
||||
|
||||
eq_("\xe9foo bar", g[0].name)
|
||||
eq_(['efoo', 'bar'], g[0].words)
|
||||
|
||||
def test_load_invalid_xml(self):
|
||||
f = io.BytesIO()
|
||||
f.write(b'<this is invalid')
|
||||
f.seek(0)
|
||||
app = DupeGuru()
|
||||
r = Results(app)
|
||||
r.load_from_xml(f,None)
|
||||
eq_(0,len(r.groups))
|
||||
|
||||
r.load_from_xml(f, None)
|
||||
eq_(0, len(r.groups))
|
||||
|
||||
def test_load_non_existant_xml(self):
|
||||
app = DupeGuru()
|
||||
r = Results(app)
|
||||
@ -626,8 +624,8 @@ class TestCaseResultsXML:
|
||||
r.load_from_xml('does_not_exist.xml', None)
|
||||
except IOError:
|
||||
self.fail()
|
||||
eq_(0,len(r.groups))
|
||||
|
||||
eq_(0, len(r.groups))
|
||||
|
||||
def test_remember_match_percentage(self):
|
||||
group = self.groups[0]
|
||||
d1, d2, d3 = group
|
||||
@ -652,7 +650,7 @@ class TestCaseResultsXML:
|
||||
group.switch_ref(d2)
|
||||
match = group.get_match_of(d3) #d2 - d3
|
||||
eq_(46, match[2])
|
||||
|
||||
|
||||
def test_save_and_load(self):
|
||||
# previously, when reloading matches, they wouldn't be reloaded as namedtuples
|
||||
f = io.BytesIO()
|
||||
@ -660,17 +658,17 @@ class TestCaseResultsXML:
|
||||
f.seek(0)
|
||||
self.results.load_from_xml(f, self.get_file)
|
||||
first(self.results.groups[0].matches).percentage
|
||||
|
||||
|
||||
def test_apply_filter_works_on_paths(self):
|
||||
# apply_filter() searches on the whole path, not just on the filename.
|
||||
self.results.apply_filter('basepath')
|
||||
eq_(len(self.results.groups), 2)
|
||||
|
||||
|
||||
def test_save_xml_with_invalid_characters(self):
|
||||
# Don't crash when saving files that have invalid xml characters in their path
|
||||
self.objects[0].name = 'foo\x19'
|
||||
self.results.save_to_xml(io.BytesIO()) # don't crash
|
||||
|
||||
|
||||
|
||||
class TestCaseResultsFilter:
|
||||
def setup_method(self, method):
|
||||
@ -679,40 +677,40 @@ class TestCaseResultsFilter:
|
||||
self.objects, self.matches, self.groups = GetTestGroups()
|
||||
self.results.groups = self.groups
|
||||
self.results.apply_filter(r'foo')
|
||||
|
||||
|
||||
def test_groups(self):
|
||||
eq_(1, len(self.results.groups))
|
||||
assert self.results.groups[0] is self.groups[0]
|
||||
|
||||
|
||||
def test_dupes(self):
|
||||
# There are 2 objects matching. The first one is ref. Only the 3rd one is supposed to be in dupes.
|
||||
eq_(1, len(self.results.dupes))
|
||||
assert self.results.dupes[0] is self.objects[2]
|
||||
|
||||
|
||||
def test_cancel_filter(self):
|
||||
self.results.apply_filter(None)
|
||||
eq_(3, len(self.results.dupes))
|
||||
eq_(2, len(self.results.groups))
|
||||
|
||||
|
||||
def test_dupes_reconstructed_filtered(self):
|
||||
# make_ref resets self.__dupes to None. When it's reconstructed, we want it filtered
|
||||
dupe = self.results.dupes[0] #3rd object
|
||||
self.results.make_ref(dupe)
|
||||
eq_(1, len(self.results.dupes))
|
||||
assert self.results.dupes[0] is self.objects[0]
|
||||
|
||||
|
||||
def test_include_ref_dupes_in_filter(self):
|
||||
# When only the ref of a group match the filter, include it in the group
|
||||
self.results.apply_filter(None)
|
||||
self.results.apply_filter(r'foo bar')
|
||||
eq_(1, len(self.results.groups))
|
||||
eq_(0, len(self.results.dupes))
|
||||
|
||||
|
||||
def test_filters_build_on_one_another(self):
|
||||
self.results.apply_filter(r'bar')
|
||||
eq_(1, len(self.results.groups))
|
||||
eq_(0, len(self.results.dupes))
|
||||
|
||||
|
||||
def test_stat_line(self):
|
||||
expected = '0 / 1 (0.00 B / 1.00 B) duplicates marked. filter: foo'
|
||||
eq_(expected, self.results.stat_line)
|
||||
@ -722,7 +720,7 @@ class TestCaseResultsFilter:
|
||||
self.results.apply_filter(None)
|
||||
expected = '0 / 3 (0.00 B / 1.01 KB) duplicates marked.'
|
||||
eq_(expected, self.results.stat_line)
|
||||
|
||||
|
||||
def test_mark_count_is_filtered_as_well(self):
|
||||
self.results.apply_filter(None)
|
||||
# We don't want to perform mark_all() because we want the mark list to contain objects
|
||||
@ -731,18 +729,18 @@ class TestCaseResultsFilter:
|
||||
self.results.apply_filter(r'foo')
|
||||
expected = '1 / 1 (1.00 B / 1.00 B) duplicates marked. filter: foo'
|
||||
eq_(expected, self.results.stat_line)
|
||||
|
||||
|
||||
def test_mark_all_only_affects_filtered_items(self):
|
||||
# When performing actions like mark_all() and mark_none in a filtered environment, only mark
|
||||
# items that are actually in the filter.
|
||||
self.results.mark_all()
|
||||
self.results.apply_filter(None)
|
||||
eq_(self.results.mark_count, 1)
|
||||
|
||||
|
||||
def test_sort_groups(self):
|
||||
self.results.apply_filter(None)
|
||||
self.results.make_ref(self.objects[1]) # to have the 1024 b obkect as ref
|
||||
g1,g2 = self.groups
|
||||
g1, g2 = self.groups
|
||||
self.results.apply_filter('a') # Matches both group
|
||||
self.results.sort_groups('size')
|
||||
assert self.results.groups[0] is g2
|
||||
@ -754,43 +752,43 @@ class TestCaseResultsFilter:
|
||||
self.results.apply_filter('a')
|
||||
assert self.results.groups[1] is g2
|
||||
assert self.results.groups[0] is g1
|
||||
|
||||
|
||||
def test_set_group(self):
|
||||
#We want the new group to be filtered
|
||||
self.objects, self.matches, self.groups = GetTestGroups()
|
||||
self.results.groups = self.groups
|
||||
eq_(1, len(self.results.groups))
|
||||
assert self.results.groups[0] is self.groups[0]
|
||||
|
||||
|
||||
def test_load_cancels_filter(self, tmpdir):
|
||||
def get_file(path):
|
||||
return [f for f in self.objects if str(f.path) == path][0]
|
||||
|
||||
|
||||
filename = str(tmpdir.join('dupeguru_results.xml'))
|
||||
self.objects[4].name = 'ibabtu 2' #we can't have 2 files with the same path
|
||||
self.results.save_to_xml(filename)
|
||||
app = DupeGuru()
|
||||
r = Results(app)
|
||||
r.apply_filter('foo')
|
||||
r.load_from_xml(filename,get_file)
|
||||
eq_(2,len(r.groups))
|
||||
|
||||
r.load_from_xml(filename, get_file)
|
||||
eq_(2, len(r.groups))
|
||||
|
||||
def test_remove_dupe(self):
|
||||
self.results.remove_duplicates([self.results.dupes[0]])
|
||||
self.results.apply_filter(None)
|
||||
eq_(2,len(self.results.groups))
|
||||
eq_(2,len(self.results.dupes))
|
||||
eq_(2, len(self.results.groups))
|
||||
eq_(2, len(self.results.dupes))
|
||||
self.results.apply_filter('ibabtu')
|
||||
self.results.remove_duplicates([self.results.dupes[0]])
|
||||
self.results.apply_filter(None)
|
||||
eq_(1,len(self.results.groups))
|
||||
eq_(1,len(self.results.dupes))
|
||||
|
||||
eq_(1, len(self.results.groups))
|
||||
eq_(1, len(self.results.dupes))
|
||||
|
||||
def test_filter_is_case_insensitive(self):
|
||||
self.results.apply_filter(None)
|
||||
self.results.apply_filter('FOO')
|
||||
eq_(1, len(self.results.dupes))
|
||||
|
||||
|
||||
def test_make_ref_on_filtered_out_doesnt_mess_stats(self):
|
||||
# When filtered, a group containing filtered out dupes will display them as being reference.
|
||||
# When calling make_ref on such a dupe, the total size and dupecount stats gets messed up
|
||||
@ -804,7 +802,7 @@ class TestCaseResultsFilter:
|
||||
self.results.apply_filter(None) # Now let's make sure our unfiltered results aren't fucked up
|
||||
expected = '0 / 3 (0.00 B / 3.00 B) duplicates marked.'
|
||||
eq_(expected, self.results.stat_line)
|
||||
|
||||
|
||||
|
||||
class TestCaseResultsRefFile:
|
||||
def setup_method(self, method):
|
||||
@ -814,8 +812,8 @@ class TestCaseResultsRefFile:
|
||||
self.objects[0].is_ref = True
|
||||
self.objects[1].is_ref = True
|
||||
self.results.groups = self.groups
|
||||
|
||||
|
||||
def test_stat_line(self):
|
||||
expected = '0 / 2 (0.00 B / 2.00 B) duplicates marked.'
|
||||
eq_(expected, self.results.stat_line)
|
||||
|
||||
|
||||
|
@ -88,10 +88,10 @@ def test_priorize(fake_fileexists):
|
||||
f[3].is_ref = True
|
||||
r = s.get_dupe_groups(f)
|
||||
g1, g2 = r
|
||||
assert f[1] in (g1.ref,g2.ref)
|
||||
assert f[0] in (g1.dupes[0],g2.dupes[0])
|
||||
assert f[3] in (g1.ref,g2.ref)
|
||||
assert f[2] in (g1.dupes[0],g2.dupes[0])
|
||||
assert f[1] in (g1.ref, g2.ref)
|
||||
assert f[0] in (g1.dupes[0], g2.dupes[0])
|
||||
assert f[3] in (g1.ref, g2.ref)
|
||||
assert f[2] in (g1.dupes[0], g2.dupes[0])
|
||||
|
||||
def test_content_scan(fake_fileexists):
|
||||
s = Scanner()
|
||||
@ -135,7 +135,7 @@ def test_min_match_perc_doesnt_matter_for_content_scan(fake_fileexists):
|
||||
def test_content_scan_doesnt_put_md5_in_words_at_the_end(fake_fileexists):
|
||||
s = Scanner()
|
||||
s.scan_type = ScanType.Contents
|
||||
f = [no('foo'),no('bar')]
|
||||
f = [no('foo'), no('bar')]
|
||||
f[0].md5 = f[0].md5partial = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'
|
||||
f[1].md5 = f[1].md5partial = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'
|
||||
r = s.get_dupe_groups(f)
|
||||
@ -209,7 +209,7 @@ def test_tag_scan(fake_fileexists):
|
||||
o1.title = 'The Air Near My Fingers'
|
||||
o2.artist = 'The White Stripes'
|
||||
o2.title = 'The Air Near My Fingers'
|
||||
r = s.get_dupe_groups([o1,o2])
|
||||
r = s.get_dupe_groups([o1, o2])
|
||||
eq_(len(r), 1)
|
||||
|
||||
def test_tag_with_album_scan(fake_fileexists):
|
||||
@ -228,7 +228,7 @@ def test_tag_with_album_scan(fake_fileexists):
|
||||
o3.artist = 'The White Stripes'
|
||||
o3.title = 'The Air Near My Fingers'
|
||||
o3.album = 'foobar'
|
||||
r = s.get_dupe_groups([o1,o2,o3])
|
||||
r = s.get_dupe_groups([o1, o2, o3])
|
||||
eq_(len(r), 1)
|
||||
|
||||
def test_that_dash_in_tags_dont_create_new_fields(fake_fileexists):
|
||||
@ -244,7 +244,7 @@ def test_that_dash_in_tags_dont_create_new_fields(fake_fileexists):
|
||||
o2.artist = 'The White Stripes - b'
|
||||
o2.title = 'The Air Near My Fingers - b'
|
||||
o2.album = 'Elephant - b'
|
||||
r = s.get_dupe_groups([o1,o2])
|
||||
r = s.get_dupe_groups([o1, o2])
|
||||
eq_(len(r), 1)
|
||||
|
||||
def test_tag_scan_with_different_scanned(fake_fileexists):
|
||||
@ -344,9 +344,9 @@ def test_ignore_list(fake_fileexists):
|
||||
f2.path = Path('dir2/foobar')
|
||||
f3.path = Path('dir3/foobar')
|
||||
ignore_list = IgnoreList()
|
||||
ignore_list.Ignore(str(f1.path),str(f2.path))
|
||||
ignore_list.Ignore(str(f1.path),str(f3.path))
|
||||
r = s.get_dupe_groups([f1,f2,f3], ignore_list=ignore_list)
|
||||
ignore_list.Ignore(str(f1.path), str(f2.path))
|
||||
ignore_list.Ignore(str(f1.path), str(f3.path))
|
||||
r = s.get_dupe_groups([f1, f2, f3], ignore_list=ignore_list)
|
||||
eq_(len(r), 1)
|
||||
g = r[0]
|
||||
eq_(len(g.dupes), 1)
|
||||
@ -367,9 +367,9 @@ def test_ignore_list_checks_for_unicode(fake_fileexists):
|
||||
f2.path = Path('foo2\u00e9')
|
||||
f3.path = Path('foo3\u00e9')
|
||||
ignore_list = IgnoreList()
|
||||
ignore_list.Ignore(str(f1.path),str(f2.path))
|
||||
ignore_list.Ignore(str(f1.path),str(f3.path))
|
||||
r = s.get_dupe_groups([f1,f2,f3], ignore_list=ignore_list)
|
||||
ignore_list.Ignore(str(f1.path), str(f2.path))
|
||||
ignore_list.Ignore(str(f1.path), str(f3.path))
|
||||
r = s.get_dupe_groups([f1, f2, f3], ignore_list=ignore_list)
|
||||
eq_(len(r), 1)
|
||||
g = r[0]
|
||||
eq_(len(g.dupes), 1)
|
||||
@ -398,7 +398,7 @@ def test_size_threshold(fake_fileexists):
|
||||
f2 = no('foo', 2, path='p2')
|
||||
f3 = no('foo', 3, path='p3')
|
||||
s.size_threshold = 2
|
||||
groups = s.get_dupe_groups([f1,f2,f3])
|
||||
groups = s.get_dupe_groups([f1, f2, f3])
|
||||
eq_(len(groups), 1)
|
||||
[group] = groups
|
||||
eq_(len(group), 2)
|
||||
@ -471,9 +471,11 @@ def test_dont_group_files_that_dont_exist(tmpdir):
|
||||
p['file1'].open('w').write('foo')
|
||||
p['file2'].open('w').write('foo')
|
||||
file1, file2 = fs.get_files(p)
|
||||
|
||||
def getmatches(*args, **kw):
|
||||
file2.path.remove()
|
||||
return [Match(file1, file2, 100)]
|
||||
|
||||
s._getmatches = getmatches
|
||||
|
||||
assert not s.get_dupe_groups([file1, file2])
|
||||
|
@ -1,17 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2009-10-23
|
||||
# Copyright 2015 Hardcoded Software (http://www.hardcoded.net)
|
||||
#
|
||||
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# Copyright 2016 Hardcoded Software (http://www.hardcoded.net)
|
||||
#
|
||||
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
from hscommon.path import Path
|
||||
|
||||
from core.engine import getwords
|
||||
from core.tests.scanner_test import NamedObject, no
|
||||
from ..scanner import *
|
||||
from core.tests.scanner_test import no
|
||||
from ..scanner import ScannerME
|
||||
|
||||
def pytest_funcarg__fake_fileexists(request):
|
||||
# This is a hack to avoid invalidating all previous tests since the scanner started to test
|
||||
|
@ -1,9 +1,7 @@
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2006/09/01
|
||||
# Copyright 2015 Hardcoded Software (http://www.hardcoded.net)
|
||||
#
|
||||
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# Copyright 2016 Hardcoded Software (http://www.hardcoded.net)
|
||||
#
|
||||
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.gnu.org/licenses/gpl-3.0.html
|
||||
# The commented out tests are tests for function that have been converted to pure C for speed
|
||||
|
||||
@ -11,26 +9,26 @@ from pytest import raises, skip
|
||||
from hscommon.testutil import eq_
|
||||
|
||||
try:
|
||||
from ..block import *
|
||||
from ..block import avgdiff, getblocks2, NoBlocksError, DifferentBlockCountError
|
||||
except ImportError:
|
||||
skip("Can't import the block module, probably hasn't been compiled.")
|
||||
|
||||
def my_avgdiff(first, second, limit=768, min_iter=3): # this is so I don't have to re-write every call
|
||||
return avgdiff(first, second, limit, min_iter)
|
||||
|
||||
BLACK = (0,0,0)
|
||||
RED = (0xff,0,0)
|
||||
GREEN = (0,0xff,0)
|
||||
BLUE = (0,0,0xff)
|
||||
BLACK = (0, 0, 0)
|
||||
RED = (0xff, 0, 0)
|
||||
GREEN = (0, 0xff, 0)
|
||||
BLUE = (0, 0, 0xff)
|
||||
|
||||
class FakeImage:
|
||||
def __init__(self, size, data):
|
||||
self.size = size
|
||||
self.data = data
|
||||
|
||||
|
||||
def getdata(self):
|
||||
return self.data
|
||||
|
||||
|
||||
def crop(self, box):
|
||||
pixels = []
|
||||
for i in range(box[1], box[3]):
|
||||
@ -40,276 +38,275 @@ class FakeImage:
|
||||
return FakeImage((box[2] - box[0], box[3] - box[1]), pixels)
|
||||
|
||||
def empty():
|
||||
return FakeImage((0,0), [])
|
||||
return FakeImage((0, 0), [])
|
||||
|
||||
def single_pixel(): #one red pixel
|
||||
return FakeImage((1, 1), [(0xff,0,0)])
|
||||
return FakeImage((1, 1), [(0xff, 0, 0)])
|
||||
|
||||
def four_pixels():
|
||||
pixels = [RED,(0,0x80,0xff),(0x80,0,0),(0,0x40,0x80)]
|
||||
pixels = [RED, (0, 0x80, 0xff), (0x80, 0, 0), (0, 0x40, 0x80)]
|
||||
return FakeImage((2, 2), pixels)
|
||||
|
||||
class TestCasegetblock:
|
||||
def test_single_pixel(self):
|
||||
im = single_pixel()
|
||||
[b] = getblocks2(im, 1)
|
||||
eq_(RED,b)
|
||||
|
||||
eq_(RED, b)
|
||||
|
||||
def test_no_pixel(self):
|
||||
im = empty()
|
||||
eq_([], getblocks2(im, 1))
|
||||
|
||||
|
||||
def test_four_pixels(self):
|
||||
im = four_pixels()
|
||||
[b] = getblocks2(im, 1)
|
||||
meanred = (0xff + 0x80) // 4
|
||||
meangreen = (0x80 + 0x40) // 4
|
||||
meanblue = (0xff + 0x80) // 4
|
||||
eq_((meanred,meangreen,meanblue),b)
|
||||
|
||||
eq_((meanred, meangreen, meanblue), b)
|
||||
|
||||
|
||||
# class TCdiff(unittest.TestCase):
|
||||
# def test_diff(self):
|
||||
# b1 = (10, 20, 30)
|
||||
# b2 = (1, 2, 3)
|
||||
# eq_(9 + 18 + 27,diff(b1,b2))
|
||||
#
|
||||
# eq_(9 + 18 + 27, diff(b1, b2))
|
||||
#
|
||||
# def test_diff_negative(self):
|
||||
# b1 = (10, 20, 30)
|
||||
# b2 = (1, 2, 3)
|
||||
# eq_(9 + 18 + 27,diff(b2,b1))
|
||||
#
|
||||
# eq_(9 + 18 + 27, diff(b2, b1))
|
||||
#
|
||||
# def test_diff_mixed_positive_and_negative(self):
|
||||
# b1 = (1, 5, 10)
|
||||
# b2 = (10, 1, 15)
|
||||
# eq_(9 + 4 + 5,diff(b1,b2))
|
||||
#
|
||||
# eq_(9 + 4 + 5, diff(b1, b2))
|
||||
#
|
||||
|
||||
# class TCgetblocks(unittest.TestCase):
|
||||
# def test_empty_image(self):
|
||||
# im = empty()
|
||||
# blocks = getblocks(im,1)
|
||||
# eq_(0,len(blocks))
|
||||
#
|
||||
# blocks = getblocks(im, 1)
|
||||
# eq_(0, len(blocks))
|
||||
#
|
||||
# def test_one_block_image(self):
|
||||
# im = four_pixels()
|
||||
# blocks = getblocks2(im, 1)
|
||||
# eq_(1,len(blocks))
|
||||
# eq_(1, len(blocks))
|
||||
# block = blocks[0]
|
||||
# meanred = (0xff + 0x80) // 4
|
||||
# meangreen = (0x80 + 0x40) // 4
|
||||
# meanblue = (0xff + 0x80) // 4
|
||||
# eq_((meanred,meangreen,meanblue),block)
|
||||
#
|
||||
# eq_((meanred, meangreen, meanblue), block)
|
||||
#
|
||||
# def test_not_enough_height_to_fit_a_block(self):
|
||||
# im = FakeImage((2,1), [BLACK, BLACK])
|
||||
# blocks = getblocks(im,2)
|
||||
# eq_(0,len(blocks))
|
||||
#
|
||||
# im = FakeImage((2, 1), [BLACK, BLACK])
|
||||
# blocks = getblocks(im, 2)
|
||||
# eq_(0, len(blocks))
|
||||
#
|
||||
# def xtest_dont_include_leftovers(self):
|
||||
# # this test is disabled because getblocks is not used and getblock in cdeffed
|
||||
# pixels = [
|
||||
# RED,(0,0x80,0xff),BLACK,
|
||||
# (0x80,0,0),(0,0x40,0x80),BLACK,
|
||||
# BLACK,BLACK,BLACK
|
||||
# RED,(0, 0x80, 0xff), BLACK,
|
||||
# (0x80, 0, 0),(0, 0x40, 0x80), BLACK,
|
||||
# BLACK, BLACK, BLACK
|
||||
# ]
|
||||
# im = FakeImage((3,3), pixels)
|
||||
# blocks = getblocks(im,2)
|
||||
# im = FakeImage((3, 3), pixels)
|
||||
# blocks = getblocks(im, 2)
|
||||
# block = blocks[0]
|
||||
# #Because the block is smaller than the image, only blocksize must be considered.
|
||||
# meanred = (0xff + 0x80) // 4
|
||||
# meangreen = (0x80 + 0x40) // 4
|
||||
# meanblue = (0xff + 0x80) // 4
|
||||
# eq_((meanred,meangreen,meanblue),block)
|
||||
#
|
||||
# eq_((meanred, meangreen, meanblue), block)
|
||||
#
|
||||
# def xtest_two_blocks(self):
|
||||
# # this test is disabled because getblocks is not used and getblock in cdeffed
|
||||
# pixels = [BLACK for i in xrange(4 * 2)]
|
||||
# pixels[0] = RED
|
||||
# pixels[1] = (0,0x80,0xff)
|
||||
# pixels[4] = (0x80,0,0)
|
||||
# pixels[5] = (0,0x40,0x80)
|
||||
# pixels[1] = (0, 0x80, 0xff)
|
||||
# pixels[4] = (0x80, 0, 0)
|
||||
# pixels[5] = (0, 0x40, 0x80)
|
||||
# im = FakeImage((4, 2), pixels)
|
||||
# blocks = getblocks(im,2)
|
||||
# eq_(2,len(blocks))
|
||||
# blocks = getblocks(im, 2)
|
||||
# eq_(2, len(blocks))
|
||||
# block = blocks[0]
|
||||
# #Because the block is smaller than the image, only blocksize must be considered.
|
||||
# meanred = (0xff + 0x80) // 4
|
||||
# meangreen = (0x80 + 0x40) // 4
|
||||
# meanblue = (0xff + 0x80) // 4
|
||||
# eq_((meanred,meangreen,meanblue),block)
|
||||
# eq_(BLACK,blocks[1])
|
||||
#
|
||||
# eq_((meanred, meangreen, meanblue), block)
|
||||
# eq_(BLACK, blocks[1])
|
||||
#
|
||||
# def test_four_blocks(self):
|
||||
# pixels = [BLACK for i in xrange(4 * 4)]
|
||||
# pixels[0] = RED
|
||||
# pixels[1] = (0,0x80,0xff)
|
||||
# pixels[4] = (0x80,0,0)
|
||||
# pixels[5] = (0,0x40,0x80)
|
||||
# pixels[1] = (0, 0x80, 0xff)
|
||||
# pixels[4] = (0x80, 0, 0)
|
||||
# pixels[5] = (0, 0x40, 0x80)
|
||||
# im = FakeImage((4, 4), pixels)
|
||||
# blocks = getblocks2(im, 2)
|
||||
# eq_(4,len(blocks))
|
||||
# eq_(4, len(blocks))
|
||||
# block = blocks[0]
|
||||
# #Because the block is smaller than the image, only blocksize must be considered.
|
||||
# meanred = (0xff + 0x80) // 4
|
||||
# meangreen = (0x80 + 0x40) // 4
|
||||
# meanblue = (0xff + 0x80) // 4
|
||||
# eq_((meanred,meangreen,meanblue),block)
|
||||
# eq_(BLACK,blocks[1])
|
||||
# eq_(BLACK,blocks[2])
|
||||
# eq_(BLACK,blocks[3])
|
||||
#
|
||||
# eq_((meanred, meangreen, meanblue), block)
|
||||
# eq_(BLACK, blocks[1])
|
||||
# eq_(BLACK, blocks[2])
|
||||
# eq_(BLACK, blocks[3])
|
||||
#
|
||||
|
||||
class TestCasegetblocks2:
|
||||
def test_empty_image(self):
|
||||
im = empty()
|
||||
blocks = getblocks2(im,1)
|
||||
eq_(0,len(blocks))
|
||||
|
||||
blocks = getblocks2(im, 1)
|
||||
eq_(0, len(blocks))
|
||||
|
||||
def test_one_block_image(self):
|
||||
im = four_pixels()
|
||||
blocks = getblocks2(im,1)
|
||||
eq_(1,len(blocks))
|
||||
blocks = getblocks2(im, 1)
|
||||
eq_(1, len(blocks))
|
||||
block = blocks[0]
|
||||
meanred = (0xff + 0x80) // 4
|
||||
meangreen = (0x80 + 0x40) // 4
|
||||
meanblue = (0xff + 0x80) // 4
|
||||
eq_((meanred,meangreen,meanblue),block)
|
||||
|
||||
eq_((meanred, meangreen, meanblue), block)
|
||||
|
||||
def test_four_blocks_all_black(self):
|
||||
im = FakeImage((2, 2), [BLACK, BLACK, BLACK, BLACK])
|
||||
blocks = getblocks2(im,2)
|
||||
eq_(4,len(blocks))
|
||||
blocks = getblocks2(im, 2)
|
||||
eq_(4, len(blocks))
|
||||
for block in blocks:
|
||||
eq_(BLACK,block)
|
||||
|
||||
eq_(BLACK, block)
|
||||
|
||||
def test_two_pixels_image_horizontal(self):
|
||||
pixels = [RED,BLUE]
|
||||
pixels = [RED, BLUE]
|
||||
im = FakeImage((2, 1), pixels)
|
||||
blocks = getblocks2(im,2)
|
||||
eq_(4,len(blocks))
|
||||
eq_(RED,blocks[0])
|
||||
eq_(BLUE,blocks[1])
|
||||
eq_(RED,blocks[2])
|
||||
eq_(BLUE,blocks[3])
|
||||
|
||||
blocks = getblocks2(im, 2)
|
||||
eq_(4, len(blocks))
|
||||
eq_(RED, blocks[0])
|
||||
eq_(BLUE, blocks[1])
|
||||
eq_(RED, blocks[2])
|
||||
eq_(BLUE, blocks[3])
|
||||
|
||||
def test_two_pixels_image_vertical(self):
|
||||
pixels = [RED,BLUE]
|
||||
pixels = [RED, BLUE]
|
||||
im = FakeImage((1, 2), pixels)
|
||||
blocks = getblocks2(im,2)
|
||||
eq_(4,len(blocks))
|
||||
eq_(RED,blocks[0])
|
||||
eq_(RED,blocks[1])
|
||||
eq_(BLUE,blocks[2])
|
||||
eq_(BLUE,blocks[3])
|
||||
|
||||
blocks = getblocks2(im, 2)
|
||||
eq_(4, len(blocks))
|
||||
eq_(RED, blocks[0])
|
||||
eq_(RED, blocks[1])
|
||||
eq_(BLUE, blocks[2])
|
||||
eq_(BLUE, blocks[3])
|
||||
|
||||
|
||||
class TestCaseavgdiff:
|
||||
def test_empty(self):
|
||||
with raises(NoBlocksError):
|
||||
my_avgdiff([], [])
|
||||
|
||||
|
||||
def test_two_blocks(self):
|
||||
im = empty()
|
||||
b1 = (5,10,15)
|
||||
b2 = (255,250,245)
|
||||
b3 = (0,0,0)
|
||||
b4 = (255,0,255)
|
||||
blocks1 = [b1,b2]
|
||||
blocks2 = [b3,b4]
|
||||
b1 = (5, 10, 15)
|
||||
b2 = (255, 250, 245)
|
||||
b3 = (0, 0, 0)
|
||||
b4 = (255, 0, 255)
|
||||
blocks1 = [b1, b2]
|
||||
blocks2 = [b3, b4]
|
||||
expected1 = 5 + 10 + 15
|
||||
expected2 = 0 + 250 + 10
|
||||
expected = (expected1 + expected2) // 2
|
||||
eq_(expected, my_avgdiff(blocks1, blocks2))
|
||||
|
||||
|
||||
def test_blocks_not_the_same_size(self):
|
||||
b = (0,0,0)
|
||||
b = (0, 0, 0)
|
||||
with raises(DifferentBlockCountError):
|
||||
my_avgdiff([b,b],[b])
|
||||
|
||||
my_avgdiff([b, b], [b])
|
||||
|
||||
def test_first_arg_is_empty_but_not_second(self):
|
||||
#Don't return 0 (as when the 2 lists are empty), raise!
|
||||
b = (0,0,0)
|
||||
b = (0, 0, 0)
|
||||
with raises(DifferentBlockCountError):
|
||||
my_avgdiff([],[b])
|
||||
|
||||
my_avgdiff([], [b])
|
||||
|
||||
def test_limit(self):
|
||||
ref = (0,0,0)
|
||||
b1 = (10,10,10) #avg 30
|
||||
b2 = (20,20,20) #avg 45
|
||||
b3 = (30,30,30) #avg 60
|
||||
blocks1 = [ref,ref,ref]
|
||||
blocks2 = [b1,b2,b3]
|
||||
eq_(45,my_avgdiff(blocks1,blocks2,44))
|
||||
|
||||
ref = (0, 0, 0)
|
||||
b1 = (10, 10, 10) #avg 30
|
||||
b2 = (20, 20, 20) #avg 45
|
||||
b3 = (30, 30, 30) #avg 60
|
||||
blocks1 = [ref, ref, ref]
|
||||
blocks2 = [b1, b2, b3]
|
||||
eq_(45, my_avgdiff(blocks1, blocks2, 44))
|
||||
|
||||
def test_min_iterations(self):
|
||||
ref = (0,0,0)
|
||||
b1 = (10,10,10) #avg 30
|
||||
b2 = (20,20,20) #avg 45
|
||||
b3 = (10,10,10) #avg 40
|
||||
blocks1 = [ref,ref,ref]
|
||||
blocks2 = [b1,b2,b3]
|
||||
eq_(40,my_avgdiff(blocks1,blocks2,45 - 1,3))
|
||||
ref = (0, 0, 0)
|
||||
b1 = (10, 10, 10) #avg 30
|
||||
b2 = (20, 20, 20) #avg 45
|
||||
b3 = (10, 10, 10) #avg 40
|
||||
blocks1 = [ref, ref, ref]
|
||||
blocks2 = [b1, b2, b3]
|
||||
eq_(40, my_avgdiff(blocks1, blocks2, 45 - 1, 3))
|
||||
|
||||
# Bah, I don't know why this test fails, but I don't think it matters very much
|
||||
# def test_just_over_the_limit(self):
|
||||
# #A score just over the limit might return exactly the limit due to truncating. We should
|
||||
# #ceil() the result in this case.
|
||||
# ref = (0,0,0)
|
||||
# b1 = (10,0,0)
|
||||
# b2 = (11,0,0)
|
||||
# blocks1 = [ref,ref]
|
||||
# blocks2 = [b1,b2]
|
||||
# eq_(11,my_avgdiff(blocks1,blocks2,10))
|
||||
#
|
||||
# ref = (0, 0, 0)
|
||||
# b1 = (10, 0, 0)
|
||||
# b2 = (11, 0, 0)
|
||||
# blocks1 = [ref, ref]
|
||||
# blocks2 = [b1, b2]
|
||||
# eq_(11, my_avgdiff(blocks1, blocks2, 10))
|
||||
#
|
||||
def test_return_at_least_1_at_the_slightest_difference(self):
|
||||
ref = (0,0,0)
|
||||
b1 = (1,0,0)
|
||||
ref = (0, 0, 0)
|
||||
b1 = (1, 0, 0)
|
||||
blocks1 = [ref for i in range(250)]
|
||||
blocks2 = [ref for i in range(250)]
|
||||
blocks2[0] = b1
|
||||
eq_(1,my_avgdiff(blocks1,blocks2))
|
||||
|
||||
eq_(1, my_avgdiff(blocks1, blocks2))
|
||||
|
||||
def test_return_0_if_there_is_no_difference(self):
|
||||
ref = (0,0,0)
|
||||
blocks1 = [ref,ref]
|
||||
blocks2 = [ref,ref]
|
||||
eq_(0,my_avgdiff(blocks1,blocks2))
|
||||
|
||||
ref = (0, 0, 0)
|
||||
blocks1 = [ref, ref]
|
||||
blocks2 = [ref, ref]
|
||||
eq_(0, my_avgdiff(blocks1, blocks2))
|
||||
|
||||
|
||||
# class TCmaxdiff(unittest.TestCase):
|
||||
# def test_empty(self):
|
||||
# self.assertRaises(NoBlocksError,maxdiff,[],[])
|
||||
#
|
||||
# self.assertRaises(NoBlocksError, maxdiff,[],[])
|
||||
#
|
||||
# def test_two_blocks(self):
|
||||
# b1 = (5,10,15)
|
||||
# b2 = (255,250,245)
|
||||
# b3 = (0,0,0)
|
||||
# b4 = (255,0,255)
|
||||
# blocks1 = [b1,b2]
|
||||
# blocks2 = [b3,b4]
|
||||
# b1 = (5, 10, 15)
|
||||
# b2 = (255, 250, 245)
|
||||
# b3 = (0, 0, 0)
|
||||
# b4 = (255, 0, 255)
|
||||
# blocks1 = [b1, b2]
|
||||
# blocks2 = [b3, b4]
|
||||
# expected1 = 5 + 10 + 15
|
||||
# expected2 = 0 + 250 + 10
|
||||
# expected = max(expected1,expected2)
|
||||
# eq_(expected,maxdiff(blocks1,blocks2))
|
||||
#
|
||||
# expected = max(expected1, expected2)
|
||||
# eq_(expected, maxdiff(blocks1, blocks2))
|
||||
#
|
||||
# def test_blocks_not_the_same_size(self):
|
||||
# b = (0,0,0)
|
||||
# self.assertRaises(DifferentBlockCountError,maxdiff,[b,b],[b])
|
||||
#
|
||||
# b = (0, 0, 0)
|
||||
# self.assertRaises(DifferentBlockCountError, maxdiff,[b, b],[b])
|
||||
#
|
||||
# def test_first_arg_is_empty_but_not_second(self):
|
||||
# #Don't return 0 (as when the 2 lists are empty), raise!
|
||||
# b = (0,0,0)
|
||||
# self.assertRaises(DifferentBlockCountError,maxdiff,[],[b])
|
||||
#
|
||||
# b = (0, 0, 0)
|
||||
# self.assertRaises(DifferentBlockCountError, maxdiff,[],[b])
|
||||
#
|
||||
# def test_limit(self):
|
||||
# b1 = (5,10,15)
|
||||
# b2 = (255,250,245)
|
||||
# b3 = (0,0,0)
|
||||
# b4 = (255,0,255)
|
||||
# blocks1 = [b1,b2]
|
||||
# blocks2 = [b3,b4]
|
||||
# b1 = (5, 10, 15)
|
||||
# b2 = (255, 250, 245)
|
||||
# b3 = (0, 0, 0)
|
||||
# b4 = (255, 0, 255)
|
||||
# blocks1 = [b1, b2]
|
||||
# blocks2 = [b3, b4]
|
||||
# expected1 = 5 + 10 + 15
|
||||
# expected2 = 0 + 250 + 10
|
||||
# eq_(expected1,maxdiff(blocks1,blocks2,expected1 - 1))
|
||||
#
|
||||
# eq_(expected1, maxdiff(blocks1, blocks2, expected1 - 1))
|
||||
#
|
||||
|
@ -1,9 +1,7 @@
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2006/09/14
|
||||
# Copyright 2015 Hardcoded Software (http://www.hardcoded.net)
|
||||
#
|
||||
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# Copyright 2016 Hardcoded Software (http://www.hardcoded.net)
|
||||
#
|
||||
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
import logging
|
||||
@ -18,47 +16,47 @@ except ImportError:
|
||||
|
||||
class TestCasecolors_to_string:
|
||||
def test_no_color(self):
|
||||
eq_('',colors_to_string([]))
|
||||
|
||||
eq_('', colors_to_string([]))
|
||||
|
||||
def test_single_color(self):
|
||||
eq_('000000',colors_to_string([(0,0,0)]))
|
||||
eq_('010101',colors_to_string([(1,1,1)]))
|
||||
eq_('0a141e',colors_to_string([(10,20,30)]))
|
||||
|
||||
eq_('000000', colors_to_string([(0, 0, 0)]))
|
||||
eq_('010101', colors_to_string([(1, 1, 1)]))
|
||||
eq_('0a141e', colors_to_string([(10, 20, 30)]))
|
||||
|
||||
def test_two_colors(self):
|
||||
eq_('000102030405',colors_to_string([(0,1,2),(3,4,5)]))
|
||||
|
||||
eq_('000102030405', colors_to_string([(0, 1, 2), (3, 4, 5)]))
|
||||
|
||||
|
||||
class TestCasestring_to_colors:
|
||||
def test_empty(self):
|
||||
eq_([],string_to_colors(''))
|
||||
|
||||
eq_([], string_to_colors(''))
|
||||
|
||||
def test_single_color(self):
|
||||
eq_([(0,0,0)],string_to_colors('000000'))
|
||||
eq_([(2,3,4)],string_to_colors('020304'))
|
||||
eq_([(10,20,30)],string_to_colors('0a141e'))
|
||||
|
||||
eq_([(0, 0, 0)], string_to_colors('000000'))
|
||||
eq_([(2, 3, 4)], string_to_colors('020304'))
|
||||
eq_([(10, 20, 30)], string_to_colors('0a141e'))
|
||||
|
||||
def test_two_colors(self):
|
||||
eq_([(10,20,30),(40,50,60)],string_to_colors('0a141e28323c'))
|
||||
|
||||
eq_([(10, 20, 30), (40, 50, 60)], string_to_colors('0a141e28323c'))
|
||||
|
||||
def test_incomplete_color(self):
|
||||
# don't return anything if it's not a complete color
|
||||
eq_([],string_to_colors('102'))
|
||||
|
||||
eq_([], string_to_colors('102'))
|
||||
|
||||
|
||||
class TestCaseCache:
|
||||
def test_empty(self):
|
||||
c = Cache()
|
||||
eq_(0,len(c))
|
||||
eq_(0, len(c))
|
||||
with raises(KeyError):
|
||||
c['foo']
|
||||
|
||||
|
||||
def test_set_then_retrieve_blocks(self):
|
||||
c = Cache()
|
||||
b = [(0,0,0),(1,2,3)]
|
||||
b = [(0, 0, 0), (1, 2, 3)]
|
||||
c['foo'] = b
|
||||
eq_(b,c['foo'])
|
||||
|
||||
eq_(b, c['foo'])
|
||||
|
||||
def test_delitem(self):
|
||||
c = Cache()
|
||||
c['foo'] = ''
|
||||
@ -66,37 +64,37 @@ class TestCaseCache:
|
||||
assert 'foo' not in c
|
||||
with raises(KeyError):
|
||||
del c['foo']
|
||||
|
||||
|
||||
def test_persistance(self, tmpdir):
|
||||
DBNAME = tmpdir.join('hstest.db')
|
||||
c = Cache(str(DBNAME))
|
||||
c['foo'] = [(1,2,3)]
|
||||
c['foo'] = [(1, 2, 3)]
|
||||
del c
|
||||
c = Cache(str(DBNAME))
|
||||
eq_([(1,2,3)],c['foo'])
|
||||
|
||||
eq_([(1, 2, 3)], c['foo'])
|
||||
|
||||
def test_filter(self):
|
||||
c = Cache()
|
||||
c['foo'] = ''
|
||||
c['bar'] = ''
|
||||
c['baz'] = ''
|
||||
c.filter(lambda p:p != 'bar') #only 'bar' is removed
|
||||
eq_(2,len(c))
|
||||
c.filter(lambda p: p != 'bar') #only 'bar' is removed
|
||||
eq_(2, len(c))
|
||||
assert 'foo' in c
|
||||
assert 'baz' in c
|
||||
assert 'bar' not in c
|
||||
|
||||
|
||||
def test_clear(self):
|
||||
c = Cache()
|
||||
c['foo'] = ''
|
||||
c['bar'] = ''
|
||||
c['baz'] = ''
|
||||
c.clear()
|
||||
eq_(0,len(c))
|
||||
eq_(0, len(c))
|
||||
assert 'foo' not in c
|
||||
assert 'baz' not in c
|
||||
assert 'bar' not in c
|
||||
|
||||
|
||||
def test_corrupted_db(self, tmpdir, monkeypatch):
|
||||
# If we don't do this monkeypatching, we get a weird exception about trying to flush a
|
||||
# closed file. I've tried setting logging level and stuff, but nothing worked. So, there we
|
||||
@ -111,30 +109,30 @@ class TestCaseCache:
|
||||
del c
|
||||
c = Cache(dbname)
|
||||
eq_(c['foo'], [(1, 2, 3)])
|
||||
|
||||
|
||||
def test_by_id(self):
|
||||
# it's possible to use the cache by referring to the files by their row_id
|
||||
c = Cache()
|
||||
b = [(0,0,0),(1,2,3)]
|
||||
b = [(0, 0, 0), (1, 2, 3)]
|
||||
c['foo'] = b
|
||||
foo_id = c.get_id('foo')
|
||||
eq_(c[foo_id], b)
|
||||
|
||||
|
||||
|
||||
class TestCaseCacheSQLEscape:
|
||||
def test_contains(self):
|
||||
c = Cache()
|
||||
assert "foo'bar" not in c
|
||||
|
||||
|
||||
def test_getitem(self):
|
||||
c = Cache()
|
||||
with raises(KeyError):
|
||||
c["foo'bar"]
|
||||
|
||||
|
||||
def test_setitem(self):
|
||||
c = Cache()
|
||||
c["foo'bar"] = []
|
||||
|
||||
|
||||
def test_delitem(self):
|
||||
c = Cache()
|
||||
c["foo'bar"] = []
|
||||
@ -142,4 +140,4 @@ class TestCaseCacheSQLEscape:
|
||||
del c["foo'bar"]
|
||||
except KeyError:
|
||||
assert False
|
||||
|
||||
|
||||
|
2
tox.ini
2
tox.ini
@ -11,7 +11,7 @@ deps =
|
||||
-r{toxinidir}/requirements-extra.txt
|
||||
|
||||
[flake8]
|
||||
exclude = .tox,env,build,hscommon,qtlib,cocoalib,cocoa,help,./get-pip.py,./qt/dg_rc.py,./core*/tests,qt/run_template.py,cocoa/run_template.py,./run.py,./pkg
|
||||
exclude = .tox,env,build,hscommon,qtlib,cocoalib,cocoa,help,./qt/dg_rc.py,qt/run_template.py,cocoa/run_template.py,./run.py,./pkg
|
||||
max-line-length = 120
|
||||
ignore = W391,W293,E302,E261,E226,E227,W291,E262,E303,E265,E731
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user