mirror of
https://github.com/arsenetar/dupeguru.git
synced 2025-03-09 21:24:36 +00:00
Moved the 'markable' unit from hscommon to core.
This commit is contained in:
parent
abe25d6967
commit
01731a8277
102
core/markable.py
Normal file
102
core/markable.py
Normal file
@ -0,0 +1,102 @@
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2006/02/23
|
||||
# Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
|
||||
|
||||
# This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.hardcoded.net/licenses/bsd_license
|
||||
|
||||
class Markable:
|
||||
def __init__(self):
|
||||
self.__marked = set()
|
||||
self.__inverted = False
|
||||
|
||||
#---Private
|
||||
def __get_mark_count(self):
|
||||
if self.__inverted:
|
||||
return self._get_markable_count() - len(self.__marked)
|
||||
else:
|
||||
return len(self.__marked)
|
||||
|
||||
#---Virtual
|
||||
#About did_mark and did_unmark: They only happen what an object is actually added/removed
|
||||
# in self.__marked, and is not affected by __inverted. Thus, self.mark while __inverted
|
||||
#is True will launch _DidUnmark.
|
||||
def _did_mark(self, o):
|
||||
pass
|
||||
|
||||
def _did_unmark(self, o):
|
||||
pass
|
||||
|
||||
def _get_markable_count(self):
|
||||
return 0
|
||||
|
||||
def _is_markable(self, o):
|
||||
return True
|
||||
|
||||
#---Protected
|
||||
def _remove_mark_flag(self, o):
|
||||
try:
|
||||
self.__marked.remove(o)
|
||||
self._did_unmark(o)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
#---Public
|
||||
def is_marked(self, o):
|
||||
if not self._is_markable(o):
|
||||
return False
|
||||
is_marked = o in self.__marked
|
||||
if self.__inverted:
|
||||
is_marked = not is_marked
|
||||
return is_marked
|
||||
|
||||
def mark(self, o):
|
||||
if self.is_marked(o):
|
||||
return False
|
||||
if not self._is_markable(o):
|
||||
return False
|
||||
return self.mark_toggle(o)
|
||||
|
||||
def mark_all(self):
|
||||
self.mark_none()
|
||||
self.__inverted = True
|
||||
|
||||
def mark_invert(self):
|
||||
self.__inverted = not self.__inverted
|
||||
|
||||
def mark_none(self):
|
||||
for o in self.__marked:
|
||||
self._did_unmark(o)
|
||||
self.__marked = set()
|
||||
self.__inverted = False
|
||||
|
||||
def mark_toggle(self, o):
|
||||
try:
|
||||
self.__marked.remove(o)
|
||||
self._did_unmark(o)
|
||||
except KeyError:
|
||||
if not self._is_markable(o):
|
||||
return False
|
||||
self.__marked.add(o)
|
||||
self._did_mark(o)
|
||||
return True
|
||||
|
||||
def unmark(self, o):
|
||||
if not self.is_marked(o):
|
||||
return False
|
||||
return self.mark_toggle(o)
|
||||
|
||||
mark_count = property(__get_mark_count)
|
||||
mark_inverted = property(lambda self :self.__inverted)
|
||||
|
||||
class MarkableList(list, Markable):
|
||||
def __init__(self):
|
||||
list.__init__(self)
|
||||
Markable.__init__(self)
|
||||
|
||||
def _get_markable_count(self):
|
||||
return len(self)
|
||||
|
||||
def _is_markable(self, o):
|
||||
return o in self
|
@ -12,13 +12,14 @@ import os
|
||||
import os.path as op
|
||||
from xml.etree import ElementTree as ET
|
||||
|
||||
from . import engine
|
||||
from jobprogress.job import nulljob
|
||||
from hscommon.conflict import get_conflicted_name
|
||||
from hscommon.markable import Markable
|
||||
from hscommon.util import flatten, nonone, FileOrPath, format_size
|
||||
from hscommon.trans import tr
|
||||
|
||||
from . import engine
|
||||
from .markable import Markable
|
||||
|
||||
class Results(Markable):
|
||||
#---Override
|
||||
def __init__(self, app):
|
||||
|
157
core/tests/markable_test.py
Normal file
157
core/tests/markable_test.py
Normal file
@ -0,0 +1,157 @@
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2006/02/23
|
||||
# Copyright 2011 Hardcoded Software (http://www.hardcoded.net)
|
||||
|
||||
# This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.hardcoded.net/licenses/bsd_license
|
||||
|
||||
from hscommon.testutil import eq_
|
||||
|
||||
from ..markable import *
|
||||
|
||||
def gen():
|
||||
ml = MarkableList()
|
||||
ml.extend(list(range(10)))
|
||||
return ml
|
||||
|
||||
def test_unmarked():
|
||||
ml = gen()
|
||||
for i in ml:
|
||||
assert not ml.is_marked(i)
|
||||
|
||||
def test_mark():
|
||||
ml = gen()
|
||||
assert ml.mark(3)
|
||||
assert ml.is_marked(3)
|
||||
assert not ml.is_marked(2)
|
||||
|
||||
def test_unmark():
|
||||
ml = gen()
|
||||
ml.mark(4)
|
||||
assert ml.unmark(4)
|
||||
assert not ml.is_marked(4)
|
||||
|
||||
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)
|
||||
assert not ml.mark(5)
|
||||
ml.unmark(5)
|
||||
assert not ml.is_marked(5)
|
||||
|
||||
def test_mark_toggle():
|
||||
ml = gen()
|
||||
ml.mark_toggle(6)
|
||||
assert ml.is_marked(6)
|
||||
ml.mark_toggle(6)
|
||||
assert not ml.is_marked(6)
|
||||
ml.mark_toggle(6)
|
||||
assert ml.is_marked(6)
|
||||
|
||||
def test_is_markable():
|
||||
class Foobar(Markable):
|
||||
def _is_markable(self, o):
|
||||
return o == 'foobar'
|
||||
f = Foobar()
|
||||
assert not f.is_marked('foobar')
|
||||
assert not f.mark('foo')
|
||||
assert not f.is_marked('foo')
|
||||
f.mark_toggle('foo')
|
||||
assert not f.is_marked('foo')
|
||||
f.mark('foobar')
|
||||
assert f.is_marked('foobar')
|
||||
ml = gen()
|
||||
ml.mark(11)
|
||||
assert not ml.is_marked(11)
|
||||
|
||||
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))
|
||||
|
||||
f = Foobar()
|
||||
f.log = []
|
||||
f.mark('foo')
|
||||
f.mark('foo')
|
||||
f.mark_toggle('bar')
|
||||
f.unmark('foo')
|
||||
f.unmark('foo')
|
||||
f.mark_toggle('bar')
|
||||
eq_([(True,'foo'),(True,'bar'),(False,'foo'),(False,'bar')],f.log)
|
||||
|
||||
def test_mark_count():
|
||||
ml = gen()
|
||||
eq_(0,ml.mark_count)
|
||||
ml.mark(7)
|
||||
eq_(1,ml.mark_count)
|
||||
ml.mark(11)
|
||||
eq_(1,ml.mark_count)
|
||||
|
||||
def test_mark_none():
|
||||
log = []
|
||||
ml = gen()
|
||||
ml._did_unmark = lambda o: log.append(o)
|
||||
ml.mark(1)
|
||||
ml.mark(2)
|
||||
eq_(2,ml.mark_count)
|
||||
ml.mark_none()
|
||||
eq_(0,ml.mark_count)
|
||||
eq_([1,2],log)
|
||||
|
||||
def test_mark_all():
|
||||
ml = gen()
|
||||
eq_(0,ml.mark_count)
|
||||
ml.mark_all()
|
||||
eq_(10,ml.mark_count)
|
||||
assert ml.is_marked(1)
|
||||
|
||||
def test_mark_invert():
|
||||
ml = gen()
|
||||
ml.mark(1)
|
||||
ml.mark_invert()
|
||||
assert not ml.is_marked(1)
|
||||
assert ml.is_marked(2)
|
||||
|
||||
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.mark(1)
|
||||
ml.mark_invert()
|
||||
assert ml.mark_inverted
|
||||
assert ml.mark(1)
|
||||
assert ml.unmark(2)
|
||||
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)
|
||||
|
||||
def test_remove_mark_flag():
|
||||
ml = gen()
|
||||
ml.mark(1)
|
||||
ml._remove_mark_flag(1)
|
||||
assert not ml.is_marked(1)
|
||||
ml.mark(1)
|
||||
ml.mark_invert()
|
||||
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):
|
||||
return o != 4
|
||||
ml = MyMarkableList()
|
||||
ml.extend(list(range(10)))
|
||||
ml.mark_invert()
|
||||
assert ml.is_marked(1)
|
||||
assert not ml.is_marked(4)
|
Loading…
x
Reference in New Issue
Block a user