def test_does_not_set_modified_if_status_identical_and_no_changes( self): task_dt = datetime.datetime(2018, 1, 1, 0, 0, 0, 0, tzinfo=timezone.UTC()) current_dt = datetime.datetime(2018, 3, 3, 0, 0, 0, 0, tzinfo=timezone.UTC()) old_data = nodedata.TaskData( status='todo', modified=task_dt, created=task_dt, finished=False, ) new_data = nodedata.TaskData( status='todo', modified=None, created=None, finished=None, ) merged_data = self.update(old_data, new_data, current_dt) assert merged_data.modified == task_dt
def test_status(self): old_modified_date = datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) new_modified_date = datetime.datetime(2018, 2, 2, 0, 0, 0, tzinfo=timezone.UTC()) current_date = datetime.datetime(2018, 3, 3, 0, 0, 0, 0, tzinfo=timezone.UTC()) old_data = nodedata.TaskData(status='todo', modified=old_modified_date) new_data = nodedata.TaskData(status='wip', modified=new_modified_date) merged_data = self.update(old_data, new_data, current_date) assert merged_data.status == 'wip'
def test_does_not_set_modified_when_identical(self): task_dt = datetime.datetime(2018, 1, 1, 0, 0, 0, 0, tzinfo=timezone.UTC()) current_dt = datetime.datetime(2018, 3, 3, 0, 0, 0, 0, tzinfo=timezone.UTC()) taskdata = nodedata.TaskData( status='todo', modified=task_dt, created=task_dt, finished=False, ) merged_data = self.update(taskdata, taskdata, current_dt) assert merged_data.modified == task_dt
def test_created(self): old_created_date = datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) new_created_date = datetime.datetime(2018, 2, 2, 0, 0, 0, tzinfo=timezone.UTC()) current_date = datetime.datetime(2018, 3, 3, 0, 0, 0, 0, tzinfo=timezone.UTC()) old_data = nodedata.TaskData(status='todo', created=old_created_date) new_data = nodedata.TaskData(status='todo', created=new_created_date) merged_data = self.update(old_data, new_data, current_date) assert merged_data.created == new_created_date
def test_finished_with_date_when_already_finished(self): old_finished_date = datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) new_finished_date = datetime.datetime(2018, 2, 2, 0, 0, 0, tzinfo=timezone.UTC()) current_date = datetime.datetime(2018, 3, 3, 0, 0, 0, 0, tzinfo=timezone.UTC()) old_data = nodedata.TaskData(status='done', finished=old_finished_date) new_data = nodedata.TaskData(status='done', finished=new_finished_date) merged_data = self.update(old_data, new_data, current_date) assert merged_data.finished == old_finished_date
def test_taskdata_converts_mtask_isoformat_to_datetime_objects(self): task = { '_id': uid().hex.upper(), 'type': 'task', 'name': 'taskA', 'indent': 0, 'parent': None, 'data': { 'status': 'done', 'created': '2018-01-01T00:00:00+00:00', 'finished': '2018-01-01T00:00:00+00:00', 'modified': '2018-01-01T00:00:00+00:00' }, } result = self.mtask(json.dumps([task])) expects = [{ '_id': uid().hex.upper(), 'type': 'task', 'name': 'taskA', 'indent': 0, 'parent': None, 'data': { 'status': 'done', 'created': datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()), 'finished': datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()), 'modified': datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()), }, }] pprint.pprint(result) print('----') pprint.pprint(expects) assert result == expects
def test_does_not_change_non_null_modified(self): modified = datetime.datetime(2017, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) now = datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) taskdata = nodedata.TaskData(status='todo', modified=modified) new_taskdata = self.finalize(taskdata, now) assert new_taskdata.modified == modified
def test_does_not_set_created_already_set(self): created = datetime.datetime(2017, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) now = datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) taskdata = nodedata.TaskData(status='todo', created=created) new_taskdata = self.finalize(taskdata, now) assert new_taskdata.created == created
def test_clears_finished_when_task_incomplete(self): finished = datetime.datetime(2017, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) now = datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) taskdata = nodedata.TaskData(status='todo', finished=finished) new_taskdata = self.finalize(taskdata, now) assert new_taskdata.finished is False
def test_does_not_overwrite_finished_when_task_complete_and_finished_is_set( self): finished = datetime.datetime(2017, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) now = datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) taskdata = nodedata.TaskData(status='done', finished=finished) new_taskdata = self.finalize(taskdata, now) assert new_taskdata.finished == finished
def test_overwrites_modified(self): taskdata = nodedata.TaskData(status='todo', modified=datetime.datetime( 2017, 1, 1, 0, 0, 0, tzinfo=timezone.UTC())) dt = datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) new_taskdata = self.touch(taskdata, dt) assert new_taskdata.modified == dt
def test_updates_finished(self): # 'status' and 'finished' are inconsistent taskdata = nodedata.TaskData(status='done', finished=False) dt = datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) new_taskdata = self.touch(taskdata, dt) assert new_taskdata.finished == dt
def test_inequality(self): dt = datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) task_A = astnode.Node( _id=None, ntype='task', name='task A', data={ 'status': 'todo', 'created': dt, 'finished': False, 'modified': dt, }, children=None, ) task_B = astnode.Node( _id=None, ntype='task', name='task B', data={ 'status': 'todo', 'created': dt, 'finished': False, 'modified': dt, }, children=None, ) assert task_A != task_B
def test_task_finished_converted_to_iso8601(self): render = self.render([ astnode.Node( _id=None, ntype='task', name='task A', data={ 'status': 'todo', 'created': None, 'finished': datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()), 'modified': None, }, children=None, ) ]) assert render[0]['data']['finished'] == '2018-01-01T00:00:00+00:00'
def test_status_done(self): render = self.render([ astnode.Node( _id=None, ntype='task', name='task A', data={ 'status': 'done', 'created': None, 'finished': datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()), 'modified': None, }, children=None, ) ]) assert render == ['x task A']
def touch(self): """ Updates fields, updates modified date (even if no changes). """ utcnow = datetime.datetime.now(timezone.UTC()) new_data = self.as_dict() new_data['modified'] = utcnow new_data['created'] = self._get_updated_created_status(utcnow) new_data['finished'] = self._get_updated_finished_status(utcnow) return TaskData(**new_data)
def test_does_not_overwrite_created(self): created_dt = datetime.datetime(2017, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) current_dt = datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) taskdata = nodedata.TaskData(status='todo', created=created_dt) new_taskdata = self.touch(taskdata, current_dt) assert new_taskdata.created == created_dt
def test_sets_modified_when_null(self): taskdata = nodedata.TaskData(status='todo', modified=None) now_dt = datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) new_taskdata = self.finalize(taskdata, now_dt) assert new_taskdata.modified == now_dt
class Test__eq__: @pytest.mark.parametrize('params', [ ('todo', datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()), False, datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC())), ]) def test_equality(self, params): task_A = nodedata.TaskData(*params) task_B = nodedata.TaskData(*params) assert task_A == task_B @pytest.mark.parametrize('params', [ (datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()), False, datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC())), ]) def test_inequality(self, params): task_A = nodedata.TaskData('todo', *params) task_B = nodedata.TaskData('skip', *params) assert task_A != task_B
def update(self, data): """ Returns a new taskdata object, with non-null values from `data` assigned to it. Example: .. code-block:: python data_A = TaskData(status='todo') data_B = TaskData(status='skip', created=datetime(...)) data_merged = data_A.update(data_B) Returns: TaskData: a new taskdata object """ utcnow = datetime.datetime.now(timezone.UTC()) new_data = self.as_dict() # if no changes, nothing to do # (not same as equality, ignores None values on `data`) if all([ self.status == data.status, (self.created == data.created or data.created is None), (self.finished == data.finished or data.finished is None), (self.modified == data.modified or data.modified is None), ]): return TaskData(**new_data) # we know there is some change, so update modified new_data['modified'] = utcnow # status always correct on new obj new_data['status'] = data.status # created, if present, will always be correct on new data if data.created: new_data['created'] = data.created # finished-status if data.status not in ( 'done', 'skip'): # False if `other.status` not finished (always) new_data['finished'] = False else: if self.finished: # Finished, and `self.finished` already set new_data['finished'] = self.finished elif data.finished: # Keep Finished set in `other` new_data['finished'] = data.finished else: # set Finished to now new_data['finished'] = utcnow return TaskData(**new_data)
def finalize(self): """ Finalizes null-fields on nodes where appropriate so node is ready to save. """ utcnow = datetime.datetime.now(timezone.UTC()) new_data = self.as_dict() new_data['created'] = self._get_updated_created_status(utcnow) new_data['finished'] = self._get_updated_finished_status(utcnow) # only set modified if it is not already set. if new_data['modified'] is None: new_data['modified'] = utcnow return TaskData(**new_data)
def test_unfinished_to_finished_with_date(self): new_finished_date = datetime.datetime(2018, 2, 2, 0, 0, 0, tzinfo=timezone.UTC()) current_date = datetime.datetime(2018, 3, 3, 0, 0, 0, 0, tzinfo=timezone.UTC()) old_data = nodedata.TaskData(status='wip') new_data = nodedata.TaskData(status='done', finished=new_finished_date) merged_data = self.update(old_data, new_data, current_date) assert merged_data.finished == new_finished_date
def test_finished_to_unfinished(self): old_finished_date = datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) current_date = datetime.datetime(2018, 3, 3, 0, 0, 0, 0, tzinfo=timezone.UTC()) old_data = nodedata.TaskData(status='done', finished=old_finished_date) new_data = nodedata.TaskData(status='todo') merged_data = self.update(old_data, new_data, current_date) assert merged_data.finished is False
def test_task_nodetype(self): dt = datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) task = astnode.Node( _id=None, ntype='task', name='task A', data={ 'status': 'todo', 'created': dt, 'finished': False, 'modified': dt, }, children=None, ) assert task.type == 'task' assert task.name == 'task A'
def test_sets_data_obj(self): dt = datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) task = astnode.Node( _id=None, ntype='task', name='task A', data={ 'status': 'todo', 'created': dt, 'finished': False, 'modified': dt, }, children=None, ) new_data = nodedata.TaskData(status='done') task.data = new_data assert task.data == new_data
def test_no_parent(self): dt = datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) task = astnode.Node( _id='A910AC72BFF74C7185F3A9DACDE5B50B', ntype='task', name='task A', data={ 'status': 'todo', 'created': dt, 'finished': False, 'modified': dt, }, children=None, ) taskrepr = repr(task) expects = 'Node(type=task, name=task A, id=A910AC72BFF74C7185F3A9DACDE5B50B, parentid=None)' assert expects == taskrepr
def test_sets_data_dict(self): dt = datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) task = astnode.Node( _id=None, ntype='task', name='task A', data={ 'status': 'todo', 'created': dt, 'finished': False, 'modified': dt, }, children=None, ) new_data = { 'status': 'done', 'created': dt, 'finished': dt, 'modified': dt, } with pytest.raises(TypeError): task.data = new_data
def test_with_parent(self): dt = datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) parent = astnode.Node( _id='6FE476CAD8774F8A874D1B5305867F4F', ntype='section', name='Section', ) task = astnode.Node( _id='A910AC72BFF74C7185F3A9DACDE5B50B', ntype='task', name='task A', data={ 'status': 'todo', 'created': dt, 'finished': False, 'modified': dt, }, children=None, parent=parent, ) taskrepr = repr(task) expects = 'Node(type=task, name=task A, id=A910AC72BFF74C7185F3A9DACDE5B50B, parentid=6FE476CAD8774F8A874D1B5305867F4F)' assert expects == taskrepr
def test_does_not_set_finished_when_task_incomplete_and_finished_is_null( self): now = datetime.datetime(2018, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) taskdata = nodedata.TaskData(status='todo', finished=None) new_taskdata = self.finalize(taskdata, now) assert new_taskdata.finished is False
from taskmage2.project import taskfiles from taskmage2.asttree import asttree, astnode from taskmage2.utils import timezone import os import shutil import tempfile import json import datetime import mock ns = taskfiles.__name__ current_dt = datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=timezone.UTC()) def get_taskfile(data): """ Get a TaskFile object, with fake-read-data. Args: data (object): a native-python collection. it will be encoded as json. """ json_data = json.dumps(data) taskfile = taskfiles.TaskFile('/var/tmp/fakefile.mtask') taskfile.read = mock.Mock(return_value=json_data) return taskfile