overrides.update(config_override or dict())
for item in overrides.items():
command_args.append('rc.{0}={1}'.format(*item))
- command_args.extend(map(six.text_type, args))
+ command_args.extend([
+ x.decode('utf-8') if isinstance(x, six.binary_type)
+ else six.text_type(x) for x in args
+ ])
return command_args
def _get_version(self):
if task.saved:
for field in task._modified_fields:
add_field(field)
+
# For new tasks, pass all fields that make sense
else:
for field in task._data.keys():
+ # We cannot set stuff that's read only (ID, UUID, ..)
if field in task.read_only_fields:
continue
+ # We do not want to do field deletion for new tasks
+ if task._data[field] is None:
+ continue
+ # Otherwise we're fine
add_field(field)
return args
)
config = dict()
- config_regex = re.compile(r'^(?P<key>[^\s]+)\s+(?P<value>[^\s].+$)')
+ config_regex = re.compile(r'^(?P<key>[^\s]+)\s+(?P<value>[^\s].*$)')
for line in raw_output:
match = config_regex.match(line)
return_all=False):
command_args = self._get_command_args(
args, config_override=config_override)
- logger.debug(' '.join(command_args))
+ logger.debug(u' '.join(command_args))
+
p = subprocess.Popen(command_args, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = [x.decode('utf-8') for x in p.communicate()]
error_msg = stderr.strip()
else:
error_msg = stdout.strip()
+ error_msg += u'\nCommand used: ' + u' '.join(command_args)
raise TaskWarriorException(error_msg)
# Return all whole triplet only if explicitly asked for
REPR_OUTPUT_SIZE = 10
PENDING = 'pending'
COMPLETED = 'completed'
+DELETED = 'deleted'
+WAITING = 'waiting'
+RECURRING = 'recurring'
logger = logging.getLogger(__name__)
# their data dics are the same
return self.task == other.task and self._data == other._data
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
__repr__ = __unicode__
# If the tasks are not saved, compare the actual instances
return id(self) == id(other)
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
def __hash__(self):
if self['uuid']:
# For saved Tasks, just define equality by equality of uuids
def pending(self):
return self['status'] == six.text_type('pending')
+ @property
+ def recurring(self):
+ return self['status'] == six.text_type('recurring')
+
@property
def active(self):
return self['start'] is not None
def completed(self):
return self.filter(status=COMPLETED)
+ def deleted(self):
+ return self.filter(status=DELETED)
+
+ def waiting(self):
+ return self.filter(status=WAITING)
+
+ def recurring(self):
+ return self.filter(status=RECURRING)
+
def filter(self, *args, **kwargs):
"""
Returns a new TaskQuerySet with the given filters added.
self.tw.tasks.all()[0].done()
self.assertEqual(len(self.tw.tasks.completed()), 1)
+ def test_deleted_empty(self):
+ Task(self.tw, description="test task").save()
+ self.assertEqual(len(self.tw.tasks.deleted()), 0)
+
+ def test_deleted_non_empty(self):
+ Task(self.tw, description="test task").save()
+ self.assertEqual(len(self.tw.tasks.deleted()), 0)
+ self.tw.tasks.all()[0].delete()
+ self.assertEqual(len(self.tw.tasks.deleted()), 1)
+
+ def test_waiting_empty(self):
+ Task(self.tw, description="test task").save()
+ self.assertEqual(len(self.tw.tasks.waiting()), 0)
+
+ def test_waiting_non_empty(self):
+ Task(self.tw, description="test task").save()
+ self.assertEqual(len(self.tw.tasks.waiting()), 0)
+
+ t = self.tw.tasks.all()[0]
+ t['wait'] = datetime.datetime.now() + datetime.timedelta(days=1)
+ t.save()
+
+ self.assertEqual(len(self.tw.tasks.waiting()), 1)
+
+ def test_recurring_empty(self):
+ Task(self.tw, description="test task").save()
+ self.assertEqual(len(self.tw.tasks.recurring()), 0)
+
+ def test_recurring_non_empty(self):
+ Task(self.tw, description="test task", recur="daily",
+ due=datetime.datetime.now()).save()
+ self.assertEqual(len(self.tw.tasks.recurring()), 1)
+
def test_filtering_by_attribute(self):
Task(self.tw, description="no priority task").save()
Task(self.tw, priority="H", description="high priority task").save()
t2 = self.tw.tasks.get(uuid=t1['uuid'])
self.assertEqual(t1.__hash__(), t2.__hash__())
+ def test_hash_unequal_unsaved_tasks(self):
+ # Compare the hash of the task using two different objects
+ t1 = Task(self.tw, description="test task 1")
+ t2 = Task(self.tw, description="test task 2")
+
+ self.assertNotEqual(t1.__hash__(), t2.__hash__())
+
+ def test_hash_unequal_saved_tasks(self):
+ # Compare the hash of the task using two different objects
+ t1 = Task(self.tw, description="test task 1")
+ t2 = Task(self.tw, description="test task 2")
+
+ t1.save()
+ t2.save()
+
+ self.assertNotEqual(t1.__hash__(), t2.__hash__())
+
def test_adding_task_with_priority(self):
t = Task(self.tw, description="test task", priority="M")
t.save()
def test_normal_to_lazy_equality(self):
assert self.stored == self.lazy
+ assert not self.stored != self.lazy
assert type(self.lazy) is LazyUUIDTask
def test_lazy_to_lazy_equality(self):
lazy2 = LazyUUIDTask(self.tw, self.stored['uuid'])
assert lazy1 == lazy2
+ assert not lazy1 != lazy2
+ assert type(lazy1) is LazyUUIDTask
+ assert type(lazy2) is LazyUUIDTask
+
+ def test_normal_to_lazy_inequality(self):
+ # Create a different UUID by changing the last letter
+ wrong_uuid = self.stored['uuid']
+ wrong_uuid = wrong_uuid[:-1] + ('a' if wrong_uuid[-1] != 'a' else 'b')
+
+ wrong_lazy = LazyUUIDTask(self.tw, wrong_uuid)
+
+ assert not self.stored == wrong_lazy
+ assert self.stored != wrong_lazy
+ assert type(wrong_lazy) is LazyUUIDTask
+
+ def test_lazy_to_lazy_inequality(self):
+ # Create a different UUID by changing the last letter
+ wrong_uuid = self.stored['uuid']
+ wrong_uuid = wrong_uuid[:-1] + ('a' if wrong_uuid[-1] != 'a' else 'b')
+
+ lazy1 = LazyUUIDTask(self.tw, self.stored['uuid'])
+ lazy2 = LazyUUIDTask(self.tw, wrong_uuid)
+
+ assert not lazy1 == lazy2
+ assert lazy1 != lazy2
assert type(lazy1) is LazyUUIDTask
assert type(lazy2) is LazyUUIDTask
def test_config(self):
assert self.tw.config['nag'] == "You have more urgent tasks."
- assert self.tw.config['debug'] == "no"
+ assert self.tw.config['default.command'] == "next"
+ assert self.tw.config['dependency.indicator'] == "D"